From c8e3359fb45eab43a853175642fcec97993b07cb Mon Sep 17 00:00:00 2001 From: cboh4 Date: Wed, 6 Nov 2024 14:54:49 +0200 Subject: [PATCH] add events to txinfo, change logic of appending to array_log, json_log --- secret_sdk/client/lcd/api/tx.py | 78 +++++++++++++++++++++++++++++---- secret_sdk/core/tx.py | 8 ++++ test.py | 19 ++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 test.py diff --git a/secret_sdk/client/lcd/api/tx.py b/secret_sdk/client/lcd/api/tx.py index 10be3b9..aeeba73 100644 --- a/secret_sdk/client/lcd/api/tx.py +++ b/secret_sdk/client/lcd/api/tx.py @@ -224,17 +224,76 @@ def decrypt_txs_response(self, txs_response) -> TxInfo: raw_log = txs_response['raw_log'] json_log = None array_log = None + events = txs_response['events'] code = txs_response['code'] - if code == 0 and raw_log != '': - _json_log = json.loads(raw_log) - json_log = [] - for i, log in enumerate(_json_log): - if 'msg_index' not in log or not log['msg_index']: - # See https://github.com/cosmos/cosmos-sdk/pull/11147 - log['msg_index'] = i - json_log.append(TxLog(i, log.get('log'), log['events'])) - array_log = self.decrypt_logs(_json_log, nonces) + + if code == 0 and raw_log == "": + for event in events: + event_attributes = event.get('attributes', []) + msg_index_attr = next((attr for attr in event_attributes if attr.get('key') == 'msg_index'), None) + if not msg_index_attr: + continue + + msg_index = int(msg_index_attr.get('value')) + + for attr in event_attributes: + if attr.get('key') == 'msg_index': + continue + + # Try to decrypt if the event type is 'wasm' + if event.get('type') == 'wasm': + nonce = nonces[msg_index] + if nonce and len(nonce) == 32: + try: + decrypted_key = self.decrypt_data_field(base64.b64decode(attr['key']), nonce).decode('utf-8').strip() + attr['key'] = decrypted_key + except Exception: + pass + + try: + decrypted_value = self.decrypt_data_field(base64.b64decode(attr['value']), nonce).decode('utf-8').strip() + attr['value'] = decrypted_value + except Exception: + pass + + # Prepare entry for array_log + entry_to_push = { + 'msg': msg_index, + 'type': event['type'], + 'key': attr['key'], + 'value': attr['value'], + } + + # Append to array_log if entry_to_push is unique + if not any(entry == entry_to_push for entry in array_log): + array_log.append(entry_to_push) + + # Prepare entry for json_log + json_log_msg_index_entry = next((log for log in json_log if log['msg_index'] == msg_index), None) + if not json_log_msg_index_entry: + json_log.append({ + 'msg_index': msg_index, + 'events': [ + { + 'type': event['type'], + 'attributes': [{'key': attr['key'], 'value': attr['value']}] + } + ] + }) + else: + json_log_event_entry = next((log for log in json_log_msg_index_entry['events'] if log['type'] == event['type']), None) + if not json_log_event_entry: + json_log_msg_index_entry['events'].append({ + 'type': event['type'], + 'attributes': [{'key': attr['key'], 'value': attr['value']}] + }) + else: + attribute_to_push = {'key': attr['key'], 'value': attr['value']} + + # Add to attributes if not already present + if not any(attr == attribute_to_push for attr in json_log_event_entry['attributes']): + json_log_event_entry['attributes'].append(attribute_to_push) elif code != 0 and raw_log != '': try: error_message_rgx = re.compile( @@ -292,6 +351,7 @@ def decrypt_txs_response(self, txs_response) -> TxInfo: tx=decoded_tx, tx_bytes=txs_response['tx'].get('value') if txs_response['tx'] else None, rawlog=raw_log, + events=txs_response['events'], logs=array_log if array_log else json_log, data=data, gas_used=int(txs_response['gas_used']), diff --git a/secret_sdk/core/tx.py b/secret_sdk/core/tx.py index f6b7c18..759610a 100755 --- a/secret_sdk/core/tx.py +++ b/secret_sdk/core/tx.py @@ -17,6 +17,7 @@ from secret_sdk.protobuf.cosmos.tx.v1beta1 import Tx as Tx_pb from secret_sdk.protobuf.cosmos.tx.v1beta1 import TxBody as TxBody_pb from secret_sdk.util.encrypt_utils import EncryptionUtils +from secret_sdk.protobuf.tendermint.abci import Event from secret_sdk.core.compact_bit_array import CompactBitArray from secret_sdk.core.fee import Fee @@ -592,6 +593,9 @@ class TxInfo(JSONSerializable): logs: Optional[List[TxLog]] = attr.ib() """Event log information.""" + events: Optional[List[Event]] = attr.ib() + """All events emitted during transaction processing (including ante handler events).""" + gas_wanted: int = attr.ib(converter=int) """Gas requested by transaction.""" @@ -620,6 +624,7 @@ def to_data(self) -> dict: "txhash": self.txhash, "rawlog": self.rawlog, "logs": [log.to_data() for log in self.logs] if self.logs else None, + "events" : self.events, "gas_wanted": str(self.gas_wanted), "gas_used": str(self.gas_used), "timestamp": self.timestamp, @@ -639,6 +644,7 @@ def from_data(cls, data: dict) -> TxInfo: data.get("txhash"), data.get("raw_log"), parse_tx_logs(data.get("logs")), + data.get("events"), data.get("gas_wanted"), data.get("gas_used"), Tx.from_data(data.get("tx")), @@ -655,6 +661,7 @@ def to_proto(self) -> TxResponse_pb: proto.txhash = self.txhash proto.raw_log = self.rawlog proto.logs = [log.to_proto() for log in self.logs] if self.logs else None + proto.events = self.events proto.gas_wanted = self.gas_wanted proto.gas_used = self.gas_used proto.timestamp = self.timestamp @@ -670,6 +677,7 @@ def from_proto(cls, proto: TxResponse_pb) -> TxInfo: txhash=proto.txhash, rawlog=proto.raw_log, logs=parse_tx_logs_proto(proto.logs), + events=proto.events, gas_wanted=proto.gas_wanted, gas_used=proto.gas_used, timestamp=proto.timestamp, diff --git a/test.py b/test.py new file mode 100644 index 0000000..fea1fb6 --- /dev/null +++ b/test.py @@ -0,0 +1,19 @@ +import time +from secret_sdk.protobuf.cosmos.tx.v1beta1 import BroadcastMode +from secret_sdk.core import Coins +from secret_sdk.client.lcd import LCDClient +from secret_sdk.key.mnemonic import MnemonicKey + +secret = LCDClient(chain_id="secretdev-1", url='http://localhost:1317') +wallet = secret.wallet(MnemonicKey('grant rice replace explain federal release fix clever romance raise often wild taxi quarter soccer fiber love must tape steak together observe swap guitar')) +tx = wallet.send_tokens(recipient_addr='secret1ap26qrlp8mcq2pg6r47w43l0y8zkqm8a450s03', transfer_amount=Coins({'uscrt': 10**6}), broadcast_mode=BroadcastMode.BROADCAST_MODE_ASYNC) +print("tx:", tx) +while True: + try: + tx = wallet.lcd.tx.tx_info(tx.txhash) + break + except Exception as e: + time.sleep(1) + continue +print(tx) +print(tx.events) \ No newline at end of file