From 5d77a0e959f22b8b3e3caab3ded64b67c6acb345 Mon Sep 17 00:00:00 2001 From: Jarred <102614730+ripci504@users.noreply.github.com> Date: Sat, 3 Sep 2022 10:37:44 -0500 Subject: [PATCH 1/2] added python code samples to monitor payments --- .../py/monitor_incoming.py | 60 +++++++++++++++++ .../py/read_amount_received.py | 66 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py create mode 100644 content/_code-samples/monitor-payments-websocket/py/read_amount_received.py diff --git a/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py b/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py new file mode 100644 index 0000000000..f5bf175226 --- /dev/null +++ b/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py @@ -0,0 +1,60 @@ +import asyncio +import websockets +import json + +# Using client libraries for ASYNC functions and websockets are needed in python. + +# Handles incoming messages +async def handler(websocket): + message = await websocket.recv() + return message + +# Use this to send API requests +async def api_request(options, websocket): + try: + await websocket.send(json.dumps(options)) + message = await websocket.recv() + return json.loads(message) + except Exception as e: + return e + +# Tests functionality of API_Requst +async def pingpong(websocket): + command = { + "id": "on_open_ping_1", + "command": "ping" + } + value = await api_request(command, websocket) + print(value) + +async def do_subscribe(websocket): + command = await api_request({ + 'command': 'subscribe', + 'accounts': ['rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe'] + }, websocket) + + if command['status'] == 'success': + print('Successfully Subscribed!') + else: + print("Error subscribing: ", command) + print('Received message from server', await handler(websocket)) + + +async def run(): + # Opens connection to ripple testnet + async for websocket in websockets.connect('wss://s.altnet.rippletest.net:51233'): + try: + await pingpong(websocket) + await do_subscribe(websocket) + except websockets.ConnectionClosed: + print('Disconnected...') + +# Runs the webhook on a loop +def main(): + loop = asyncio.get_event_loop() + loop.run_until_complete(run()) + loop.close() + print('Restarting Loop') + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py b/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py new file mode 100644 index 0000000000..29763b2cce --- /dev/null +++ b/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py @@ -0,0 +1,66 @@ +import json + +# Helpers to find accounts in AffectedNodes and see how much the balance changed. +def FindXRPDifference(tx, address): + for i in tx['meta']['AffectedNodes']: + if 'CreatedNode' and 'ModifiedNode' in list(i): + # If a CreatedNode and a ModifiedNode both exist, the monitores account has funded another account + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] != address: + new_address = ledger_entry['NewFields']['Account'] + balance_drops = int(ledger_entry['NewFields']['Balance']) + xrp_amount = (balance_drops / 1000000) + print("A new account", new_address, "was funded with", xrp_amount, "XRP") + break + + elif list(i)[0] == 'ModifiedNode': + ledger_entry = i['ModifiedNode'] + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['FinalFields']['Account'] == address: + if not ledger_entry['PreviousFields']['Balance']: + print('Balance didnt change') + # Subtracts the previous balance from the new balance + old_balance = int(ledger_entry['PreviousFields']['Balance']) + new_balance = int(ledger_entry['FinalFields']['Balance']) + diff_in_drops = (new_balance - old_balance) + xrp_amount = (diff_in_drops / 1000000) + if xrp_amount > 0: + print("Received", xrp_amount, "XRP") + break + else: + print("Spent", abs(xrp_amount), "XRP") + break + elif list(i)[0] == 'CreatedNode': + # If there is no outgoing payment, but an account was created, the account most likely just got funded + ledger_entry = i['CreatedNode'] + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] == address: + balance_drops = int(ledger_entry['NewFields']['Balance']) + xrp_amount = (balance_drops / 1000000) + print("Received", xrp_amount, "XRP (account funded)") + break + else: + print("Did not find address in affected nodes.") + + +def CountXRPReceived(tx, address): + if tx['meta']['TransactionResult'] != 'tesSUCCESS': + print('Transaction failed') + return + if tx['transaction']['TransactionType'] == 'Payment': + if tx['transaction']['Destination'] != address: + print('Not the destination of this payment.') + return + if tx['meta']['delivered_amount'] is str: + amount_in_drops = tx['transaction']['Amount'] + xrp_amount = (amount_in_drops / 1000000) + print('Received', xrp_amount, 'XRP') + return + else: + print('Received non-XRP currency') + elif tx['transaction']['TransactionType'] == 'PaymentChannelClaim' or 'PaymentChannelFund' or'OfferCreate' or 'CheckCash' or 'EscrowFinish': + FindXRPDifference(tx, address) + else: + print('Not a currency-delivering transaction type', tx['transaction']['TransactionType']) + + +CountXRPReceived(tx=transaction, address='rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe') + + From ba7ba3035aec64e5459e7127c59adaa0df22fc84 Mon Sep 17 00:00:00 2001 From: Jarred <102614730+ripci504@users.noreply.github.com> Date: Wed, 7 Sep 2022 19:51:00 -0500 Subject: [PATCH 2/2] Higher quality code with more comments --- .../py/monitor_incoming.py | 1 + .../py/read_amount_received.py | 94 ++++++++++--------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py b/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py index f5bf175226..0e94f0588c 100644 --- a/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py +++ b/content/_code-samples/monitor-payments-websocket/py/monitor_incoming.py @@ -3,6 +3,7 @@ import websockets import json # Using client libraries for ASYNC functions and websockets are needed in python. +# To install, use terminal command 'pip install asyncio && pip install websockets' # Handles incoming messages async def handler(websocket): diff --git a/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py b/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py index 29763b2cce..5f54fcf3c5 100644 --- a/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py +++ b/content/_code-samples/monitor-payments-websocket/py/read_amount_received.py @@ -2,64 +2,72 @@ import json # Helpers to find accounts in AffectedNodes and see how much the balance changed. def FindXRPDifference(tx, address): + # Define empty list to put the Node change type in. + affected_nodes = [] + # Loop over the AffectedNodes to build a list of affected nodes for i in tx['meta']['AffectedNodes']: - if 'CreatedNode' and 'ModifiedNode' in list(i): - # If a CreatedNode and a ModifiedNode both exist, the monitores account has funded another account - if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] != address: - new_address = ledger_entry['NewFields']['Account'] - balance_drops = int(ledger_entry['NewFields']['Balance']) - xrp_amount = (balance_drops / 1000000) - print("A new account", new_address, "was funded with", xrp_amount, "XRP") - break - - elif list(i)[0] == 'ModifiedNode': - ledger_entry = i['ModifiedNode'] - if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['FinalFields']['Account'] == address: - if not ledger_entry['PreviousFields']['Balance']: - print('Balance didnt change') - # Subtracts the previous balance from the new balance - old_balance = int(ledger_entry['PreviousFields']['Balance']) - new_balance = int(ledger_entry['FinalFields']['Balance']) - diff_in_drops = (new_balance - old_balance) - xrp_amount = (diff_in_drops / 1000000) - if xrp_amount > 0: - print("Received", xrp_amount, "XRP") - break - else: - print("Spent", abs(xrp_amount), "XRP") - break - elif list(i)[0] == 'CreatedNode': - # If there is no outgoing payment, but an account was created, the account most likely just got funded - ledger_entry = i['CreatedNode'] - if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] == address: - balance_drops = int(ledger_entry['NewFields']['Balance']) - xrp_amount = (balance_drops / 1000000) - print("Received", xrp_amount, "XRP (account funded)") - break + i = list(i)[0] + affected_nodes.append(i) else: - print("Did not find address in affected nodes.") - + for i in tx['meta']['AffectedNodes']: + if 'CreatedNode' in affected_nodes and 'ModifiedNode' in affected_nodes: + # If a CreatedNode and a ModifiedNode both exist, the monitored account has funded another account + # If both exist, CreatedNode always comes after AffectedNode, so we can gather it by getting the second entry in the list by using [1] + ledger_entry = tx['meta']['AffectedNodes'][1]['CreatedNode'] + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] != address: + new_address = ledger_entry['NewFields']['Account'] + balance_drops = int(ledger_entry['NewFields']['Balance']) + xrp_amount = (balance_drops / 1000000) + print(f"A new account {new_address} was funded with {xrp_amount} XRP") + return + elif affected_nodes == ['ModifiedNode']: + ledger_entry = i['ModifiedNode'] + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['FinalFields']['Account'] == address: + if not ledger_entry['PreviousFields']['Balance']: + print("Balance didn't change") + # Subtracts the previous balance from the new balance + old_balance = int(ledger_entry['PreviousFields']['Balance']) + new_balance = int(ledger_entry['FinalFields']['Balance']) + diff_in_drops = (new_balance - old_balance) + xrp_amount = (diff_in_drops / 1000000) + if xrp_amount > 0: + print(f"Received {xrp_amount} XRP") + return + else: + print("Spent", abs(xrp_amount), "XRP") + return + elif affected_nodes == ['CreatedNode']: + # If there is no outgoing payment, but an account was created, the account most likely just got funded + ledger_entry = i['CreatedNode'] + if ledger_entry['LedgerEntryType'] == 'AccountRoot' and ledger_entry['NewFields']['Account'] == address: + balance_drops = int(ledger_entry['NewFields']['Balance']) + xrp_amount = (balance_drops / 1000000) + print(f"Received {xrp_amount} XRP (account funded)") + return + else: + print("Did not find address in affected nodes.") + +# Check how much XRP was received, if any def CountXRPReceived(tx, address): if tx['meta']['TransactionResult'] != 'tesSUCCESS': - print('Transaction failed') + print("Transaction failed") return if tx['transaction']['TransactionType'] == 'Payment': if tx['transaction']['Destination'] != address: - print('Not the destination of this payment.') + print("Not the destination of this payment.") return - if tx['meta']['delivered_amount'] is str: - amount_in_drops = tx['transaction']['Amount'] + if tx['meta']['delivered_amount'] is int or str: + amount_in_drops = int(tx['transaction']['Amount']) xrp_amount = (amount_in_drops / 1000000) - print('Received', xrp_amount, 'XRP') + print(f"Received {xrp_amount} XRP") return else: - print('Received non-XRP currency') + print("Received non-XRP currency") elif tx['transaction']['TransactionType'] == 'PaymentChannelClaim' or 'PaymentChannelFund' or'OfferCreate' or 'CheckCash' or 'EscrowFinish': FindXRPDifference(tx, address) else: - print('Not a currency-delivering transaction type', tx['transaction']['TransactionType']) - + print("Not a currency-delivering transaction type", tx['transaction']['TransactionType']) CountXRPReceived(tx=transaction, address='rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe')