produce .gif BBQr with --bbqr flag
This commit is contained in:
parent
614bef5932
commit
2d42c86e70
@ -40,6 +40,7 @@ Options:
|
||||
num-outs
|
||||
-f, --fee INTEGER Miner's fee in Satoshis
|
||||
-2, --psbt2 Make PSBTv2
|
||||
-b, --bbqr Output BBQr OUTPUT.gif in CWD
|
||||
-s, --segwit [SS] Make inputs be segwit style
|
||||
-w, --wrapped [SS] Make inputs be wrapped segwit style
|
||||
(requires --segwit flag)
|
||||
|
||||
@ -7,12 +7,15 @@
|
||||
# That will create the command "psbt_faker" in your path... or just use "./main.py ..." here
|
||||
#
|
||||
#
|
||||
import click
|
||||
import click, io, pyqrcode, os
|
||||
from binascii import b2a_hex as _b2a_hex
|
||||
from base64 import b64encode
|
||||
from decimal import Decimal
|
||||
from .txn import fake_ms_txn, fake_txn, ADDR_STYLES
|
||||
from .multisig import from_simple_text
|
||||
from bbqr import split_qrs
|
||||
from PIL import Image, ImageDraw, ImageChops
|
||||
|
||||
|
||||
b2a_hex = lambda a: str(_b2a_hex(a), 'ascii')
|
||||
#xfp2hex = lambda a: b2a_hex(a[::-1]).upper()
|
||||
@ -36,6 +39,7 @@ def repeat_until_length(values, target_length):
|
||||
@click.option('--num-change', '-c', help="Number of change outputs (default 1) from num-outs", default=1)
|
||||
@click.option('--fee', '-f', help="Miner's fee in Satoshis", default=1000)
|
||||
@click.option('--psbt2', '-2', help="Make PSBTv2", is_flag=True, default=False)
|
||||
@click.option('--bbqr', '-b', help="Output BBQr OUTPUT.gif in CWD", is_flag=True, default=False)
|
||||
@click.option('--segwit', '-s', help="[SS] Make inputs be segwit style", is_flag=True, default=False)
|
||||
@click.option('--wrapped', '-w', help="[SS] Make inputs be wrapped segwit style (requires --segwit flag)", is_flag=True, default=False)
|
||||
@click.option('--styles', '-a', help="Output address style (multiple ok). If multisig only applies to non-change addresses.", multiple=True, default=None, type=click.Choice(ADDR_STYLES))
|
||||
@ -48,7 +52,7 @@ def repeat_until_length(values, target_length):
|
||||
@click.option('--input-amount', '-n', help="Size of each input in sats (default 100k sats each input)", default=(100000,), multiple=True, type=int)
|
||||
@click.option('--incl-xpubs', '-I', help="[MS] Include XPUBs in PSBT global section", is_flag=True, default=False)
|
||||
def main(num_ins, sequence, num_change, num_outs, output_amount, out_psbt, testnet, xpub, segwit, fee, styles, base64,
|
||||
partial, zero_xfp, multisig, locktime, input_amount, psbt2, incl_xpubs, wrapped):
|
||||
partial, zero_xfp, multisig, locktime, input_amount, psbt2, incl_xpubs, wrapped, bbqr):
|
||||
'''Construct a valid PSBT which spends non-existant BTC to random addresses!'''
|
||||
|
||||
if locktime == "current":
|
||||
@ -99,8 +103,8 @@ def main(num_ins, sequence, num_change, num_outs, output_amount, out_psbt, testn
|
||||
change_outputs=change_outputs,
|
||||
psbt_v2=psbt2, sequences=sequence)
|
||||
|
||||
|
||||
out_psbt.write(psbt if not base64 else b64encode(psbt))
|
||||
res = b64encode(psbt) if base64 else psbt
|
||||
out_psbt.write(res)
|
||||
|
||||
print(f"\nFake PSBT would send {(sum(input_amount)/Decimal(1E8))} BTC to: ")
|
||||
print('\n'.join(" %.8f => %s %s" % (Decimal(amt)/Decimal(1E8),dest, ' (change back)' if chg else '')
|
||||
@ -110,6 +114,37 @@ def main(num_ins, sequence, num_change, num_outs, output_amount, out_psbt, testn
|
||||
|
||||
print("\nPSBT to be signed: " + out_psbt.name, end='\n\n')
|
||||
|
||||
if bbqr:
|
||||
bbqr_out_file = os.path.splitext(out_psbt.name)[0] + ".gif"
|
||||
vers, parts = split_qrs(res, type_code="U" if base64 else "P", encoding="2",
|
||||
max_version=20)
|
||||
qs = [pyqrcode.create(data, error='L', version=vers, mode='alphanumeric') for
|
||||
data in parts]
|
||||
|
||||
frames = []
|
||||
num_parts = len(parts)
|
||||
for i in range(num_parts):
|
||||
xbm = qs[i].xbm(scale=4, quiet_zone=10)
|
||||
img = ImageChops.invert(Image.open(io.BytesIO(xbm.encode()))).convert('L')
|
||||
if num_parts > 1:
|
||||
# add progress bar
|
||||
pw = img.width // num_parts
|
||||
lm = (img.width - (pw * num_parts)) // 2
|
||||
draw = ImageDraw.Draw(img)
|
||||
h = 4 // 2
|
||||
y = img.height - h - (4 // 2) - 1
|
||||
|
||||
for j in range(num_parts):
|
||||
draw.rectangle((lm + (j * pw), y, lm + ((j + 1) * pw), y + h), fill=(128 if i != j else 0))
|
||||
|
||||
frames.append(img)
|
||||
|
||||
if num_parts == 1:
|
||||
frames[0].save(bbqr_out_file)
|
||||
else:
|
||||
frames[0].save(bbqr_out_file, format="gif", save_all=True, loop=0,
|
||||
duration=250, default_image=False, append_images=frames[1:])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
click>=6.7
|
||||
ecdsa
|
||||
# or can use python-secp256k1
|
||||
|
||||
# BBQr library
|
||||
git+https://github.com/coinkite/BBQr.git@master#egg=bbqr&subdirectory=python
|
||||
pyqrcode
|
||||
Pillow
|
||||
7
setup.py
7
setup.py
@ -25,8 +25,11 @@ if __name__ == '__main__':
|
||||
py_modules=['psbt_faker'],
|
||||
python_requires='>3.6.0',
|
||||
install_requires=[
|
||||
'Click',
|
||||
'ecdsa',
|
||||
"click>=6.7",
|
||||
"ecdsa",
|
||||
"pyqrcode",
|
||||
"Pillow",
|
||||
"bbqr @ git+https://github.com/coinkite/BBQr.git@master#subdirectory=python",
|
||||
],
|
||||
entry_points='''
|
||||
[console_scripts]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user