diff --git a/_code-samples/airgapped-wallet/py/README.md b/_code-samples/airgapped-wallet/py/README.md index f2a7a651ca..524bb17d54 100644 --- a/_code-samples/airgapped-wallet/py/README.md +++ b/_code-samples/airgapped-wallet/py/README.md @@ -101,9 +101,7 @@ sudo apt-get install python3.8 python3-pip pip install -r requirements.txt ``` -4. Edit line 47 @ `relay-transaction.py` and insert the signed transaction blob from scanning the QR code Machine 1 generated. - -5. Run `relay-transaction.py` +4. Run `relay-transaction.py` with one argument, the signed transaction blob to submit. ## Phone Setup The phone requires a working camera that is able to scan a QR code and an internet connection for it to be able to transmit the signed transaction blob to Machine 2. diff --git a/_code-samples/airgapped-wallet/py/airgapped-wallet.py b/_code-samples/airgapped-wallet/py/airgapped-wallet.py index a8675c3c5b..be10270ea7 100644 --- a/_code-samples/airgapped-wallet/py/airgapped-wallet.py +++ b/_code-samples/airgapped-wallet/py/airgapped-wallet.py @@ -68,7 +68,9 @@ def sign_transaction(_xrp_amount, _destination, _ledger_seq, _wallet_seq, passwo amount=xrp_to_drops(xrp=_xrp_amount), destination=_destination, last_ledger_sequence=validated_seq + 100, - # +100 to catch up with the ledger when we transmit the signed tx blob to Machine 2 + # 100 ledgers usually takes about 6 minutes, so you have about that + # long to submit it before it expires. To give more time, increase + # this number; for unlimited time, remove last_ledger entirely. sequence=_wallet_seq, fee="10" ) @@ -77,7 +79,7 @@ def sign_transaction(_xrp_amount, _destination, _ledger_seq, _wallet_seq, passwo # Scan the QR code and transmit the signed_tx blob to an online machine (Machine 2) to relay it to the XRPL my_tx_payment_signed = sign(transaction=my_tx_payment, wallet=_wallet) - img = qrcode.make(my_tx_payment_signed.to_dict()) + img = qrcode.make(my_tx_payment_signed.blob()) img.save(get_path("/Wallet/transactionID.png")) image = Image.open(get_path("/Wallet/transactionID.png")) image.show() @@ -119,12 +121,15 @@ def main(): # If the Wallet's folder already exists, continue on if os.path.exists(File) and os.path.exists(get_path("/Wallet/public.txt")): while True: - ask = int(input("\n 1. Transact XRP" + try: + ask = int(input("\n 1. Transact XRP" "\n 2. Generate an XRP wallet (read only)" "\n 3. Showcase XRP Wallet Address (QR Code)" "\n 4. Exit" "\n\n Enter Index: " )) + except ValueError: + continue if ask == 1: password = str(input(" Enter Password: ")) @@ -142,6 +147,7 @@ def main(): _wallet_seq=wallet_sequence, password=password ) + print("This transaction is expected to expire in ~6 minutes.") del destination, amount, wallet_sequence, ledger_sequence diff --git a/_code-samples/airgapped-wallet/py/relay-transaction.py b/_code-samples/airgapped-wallet/py/relay-transaction.py index 876aa66620..d2f0d94b97 100644 --- a/_code-samples/airgapped-wallet/py/relay-transaction.py +++ b/_code-samples/airgapped-wallet/py/relay-transaction.py @@ -1,7 +1,8 @@ from xrpl.clients import JsonRpcClient from xrpl.models.transactions import Payment from xrpl.transaction import submit_and_wait - +from xrpl.utils import drops_to_xrp +import argparse def connect_node(_node): """ @@ -14,7 +15,7 @@ def connect_node(_node): return _client -def send_transaction(transaction_dict): +def send_transaction(tx_blob): """ Connects to a node -> Send Transaction Main Function to send transaction to the XRPL @@ -24,27 +25,29 @@ def send_transaction(transaction_dict): # TESTNET: "https://s.altnet.rippletest.net:51234/" # MAINNET: "https://s2.ripple.com:51234/" - # Since we manually inserted the tx blob, we need to initialize it into a Payment so xrpl-py could process it - my_tx_signed = Payment.from_dict(transaction_dict) + tx = submit_and_wait(transaction=tx_blob, client=client) - tx = submit_and_wait(transaction=my_tx_signed, client=client) + tx_account = tx.result["tx_json"]["Account"] + tx_hash = tx.result["hash"] + tx_destination = tx.result["tx_json"]['Destination'] + delivered = tx.result["meta"]["delivered_amount"] + if type(delivered) == str: + tx_delivered_amount = f"{drops_to_xrp(delivered)} XRP" + else: + tx_delivered_amount = f"{delivered['value']} {delivered['currency']}.{delivered['issuer']}" - tx_hash = tx.result['hash'] - tx_destination = tx.result['Destination'] - tx_xrp_amount = int(tx.result['Amount']) / 1000000 - tx_account = tx.result['Account'] print(f"\n XRPL Explorer: https://testnet.xrpl.org/transactions/{tx_hash}" + f"\n Wallet Used: {tx_account}" f"\n Transaction Hash: {tx_hash}" f"\n Transaction Destination: {tx_destination}" - f"\n Transacted XRP: {tx_xrp_amount}" - f"\n Wallet Used: {tx_account}" + f"\n Amount Delivered: {tx_delivered_amount}" ) if __name__ == '__main__': - tx_blob = "ENTER TX BLOB HERE" - if tx_blob == "ENTER TX BLOB HERE": - print("Set tx to 'tx_blob' received from scanning the QR code generated by the airgapped wallet") - else: - send_transaction(tx_blob) + p = argparse.ArgumentParser(description='Submit a signed transaction blob') + p.add_argument('blob', type=str, + help='Transaction blob (in hexadecimal) to submit') + tx_blob = p.parse_args().blob + send_transaction(tx_blob) diff --git a/_code-samples/airgapped-wallet/py/requirements.txt b/_code-samples/airgapped-wallet/py/requirements.txt index d62c9d2d7c..19fa7a080b 100644 --- a/_code-samples/airgapped-wallet/py/requirements.txt +++ b/_code-samples/airgapped-wallet/py/requirements.txt @@ -1,25 +1,4 @@ -anyio==3.2.1 -asgiref==3.4.1 -base58==2.1.0 -certifi==2024.7.4 -cffi==1.15.0 -colorama==0.4.4 cryptography==43.0.1 -Django==3.2.25 -ECPy==1.2.5 -h11==0.12.0 -httpcore==0.13.6 -idna==3.8 -image==1.5.33 -pifacedigitalio==3.0.5 Pillow==10.3.0 -pycparser==2.20 -pytz==2021.1 qrcode==7.2 -rfc3986==1.5.0 -six==1.16.0 -sniffio==1.2.0 -sqlparse==0.5.1 -typing-extensions==4.2.0 -websockets==10.0 -xrpl-py==2.0.0 +xrpl-py==3.0.0