From daec5e63e7a0f4e63323f29cb005e0c9af44e4ef Mon Sep 17 00:00:00 2001 From: pixelsoup42 Date: Tue, 12 Sep 2023 17:47:38 +0200 Subject: [PATCH] raw_assets -> raw_values --- src/cardano_account_pandas_dumper/__main__.py | 4 +- .../cardano_account_pandas_dumper.py | 96 +++++++++---------- src/cardano_account_pandas_dumper/known.jsonc | 75 ++++++++------- 3 files changed, 87 insertions(+), 88 deletions(-) diff --git a/src/cardano_account_pandas_dumper/__main__.py b/src/cardano_account_pandas_dumper/__main__.py index c448f15..2be9c96 100644 --- a/src/cardano_account_pandas_dumper/__main__.py +++ b/src/cardano_account_pandas_dumper/__main__.py @@ -82,8 +82,8 @@ def _create_arg_parser(): action="store_true", ) result.add_argument( - "--raw_asset", - help="Add header row with concatenation of policy_id and hex-encoded asset_name.", + "--raw_values", + help="Keep assets, policies and addresses as hex instead of looking up names.", action="store_true", ) result.add_argument( diff --git a/src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py b/src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py index 596164f..9530b48 100644 --- a/src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py +++ b/src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py @@ -66,16 +66,18 @@ def _transaction_data( self, api: BlockFrostApi, ) -> pd.Series: - transaction_set = set() - for addr in self.own_addresses: - for outer_tx in api.address_transactions( - addr, - to_block=self.to_block, - gather_pages=True, - ): - transaction_set.add(outer_tx.tx_hash) result_list = [] - for tx_hash in transaction_set: + for tx_hash in frozenset( + [ + outer_tx.tx_hash + for addr in self.own_addresses + for outer_tx in api.address_transactions( + addr, + to_block=self.to_block, + gather_pages=True, + ) + ] + ): transaction = api.transaction(tx_hash) transaction.utxos = api.transaction_utxos(tx_hash) transaction.utxos.nonref_inputs = [ @@ -203,20 +205,17 @@ def _reward_transactions(self, api: BlockFrostApi) -> pd.Series: class AccountPandasDumper: """Hold logic to convert an instance of AccountData to a Pandas dataframe.""" - ADDRESSES_KEY = "addresses" - POLICIES_KEY = "policies" - MUTED_POLICIES_KEY = "muted_policies" - SCRIPTS_KEY = "scripts" - LABELS_KEY = "labels" TRANSACTION_OFFSET = np.timedelta64(1000, "ns") def __init__(self, data: AccountData, known_dict: Any, args: argparse.Namespace): self.data = data self.known_dict = known_dict self.args = args - - def _format_asset(self, asset: str) -> Optional[str]: - return self.data.assets[asset].metadata.name + self.addresses = pd.Series(known_dict.get("addresses", {})) + self.policies = pd.Series(known_dict.get("policies", {})) + self.muted_policies = pd.Series(known_dict.get("muted_policies", [])) + self.scripts = pd.Series(known_dict.get("scripts", {})) + self.labels = pd.Series(known_dict.get("labels", {})) def _truncate(self, value: str) -> str: return ( @@ -225,9 +224,6 @@ def _truncate(self, value: str) -> str: else (value[: self.args.truncate_length] + "...") ) - def _format_policy(self, policy: str) -> Optional[str]: - return self.known_dict[self.POLICIES_KEY].get(policy, self._truncate(policy)) - @staticmethod def _is_hex_number(num: Any) -> bool: return isinstance(num, str) and not bool( @@ -263,10 +259,9 @@ def _munge_metadata(self, obj: blockfrost.utils.Namespace) -> Any: def _format_message(self, tx_obj: blockfrost.utils.Namespace) -> str: result: List[str] = [] for metadata_key in tx_obj.metadata: - if metadata_key.label in self.known_dict[self.LABELS_KEY]: - label = self.known_dict[self.LABELS_KEY][metadata_key.label] - else: - label = metadata_key.label + label = self.labels.get( + metadata_key.label, self._truncate(metadata_key.label) + ) val = self._munge_metadata(metadata_key.json_metadata) if ( self._is_hex_number(label) @@ -300,18 +295,19 @@ def _format_message(self, tx_obj: blockfrost.utils.Namespace) -> str: return " ".join(result).removeprefix("Message : ") def _format_script(self, script: str) -> str: - return self.known_dict[self.SCRIPTS_KEY].get( - script, - self._truncate(script), - ) + return self.scripts.get(script, self._truncate(script)) def _format_address(self, address: str) -> str: - if address in self.data.own_addresses: - return " own" - return self.known_dict[self.ADDRESSES_KEY].get( - address, - "other", - ) + return self.addresses.get(address, self._truncate(address)) + + def _format_asset_name(self, name: str) -> str: + try: + return bytes.fromhex(name).decode() + except UnicodeDecodeError: + return name + + def _format_policy(self, policy: str) -> Optional[str]: + return self.policies.get(policy, self._truncate(policy)) def _decimals_for_asset(self, asset: str) -> np.longlong: return np.longlong(self.data.assets[asset].metadata.decimals) @@ -384,23 +380,18 @@ def _drop_foreign_assets(self, balance: pd.DataFrame) -> None: balance.drop(assets_to_drop, axis=1, inplace=True) def _drop_muted_policies(self, balance: pd.DataFrame) -> None: - if ( - (not self.args.unmute) - and self.MUTED_POLICIES_KEY in self.known_dict - and self.known_dict[self.MUTED_POLICIES_KEY] - ): - policies_to_mute = frozenset(self.known_dict[self.MUTED_POLICIES_KEY]) - policies_to_drop = frozenset( - [x[0] for x in balance.columns if x[0] in policies_to_mute] - ) - balance.sort_index(inplace=True, axis=1) - balance.drop(policies_to_drop, axis=1, inplace=True) + policies_to_drop = frozenset( + [x[0] for x in balance.columns if x[0] in self.muted_policies] + ) + balance.sort_index(inplace=True, axis=1) + balance.drop(policies_to_drop, axis=1, inplace=True) def _relabel_assets(self, balance: pd.DataFrame) -> None: - new_columns = [ - (self.data.assets[x[0]].metadata.name,) + x[1:] for x in balance.columns + new_columns: List[Tuple] = [ + (self._format_policy(x[0]), self._format_asset_name(x[1])) + tuple(x[2:]) + for x in balance.columns ] - balance.columns = new_columns + balance.columns = pd.MultiIndex.from_tuples(new_columns) def make_transaction_frame(self) -> pd.DataFrame: """Build a transaction spreadsheet.""" @@ -431,8 +422,13 @@ def make_transaction_frame(self) -> pd.DataFrame: dtype=pd.Int64Dtype, ) self._drop_foreign_assets(balance) - self._drop_muted_policies(balance) - # self._relabel_assets(balance) + if not self.args.unmute: + self._drop_muted_policies(balance) + if self.args.detail_level == 1: + balance.drop(labels=False, axis=1, level=3, inplace=True) + if not self.args.raw_values: + self._relabel_assets(balance) + balance.columns = pd.MultiIndex.from_tuples(balance.columns) balance.sort_index(axis=1, level=0, sort_remaining=True, inplace=True) frame = pd.concat([timestamp, tx_hash, message], axis=1) diff --git a/src/cardano_account_pandas_dumper/known.jsonc b/src/cardano_account_pandas_dumper/known.jsonc index 71d6fc6..1c5b28e 100644 --- a/src/cardano_account_pandas_dumper/known.jsonc +++ b/src/cardano_account_pandas_dumper/known.jsonc @@ -5,7 +5,6 @@ "addr1v95sf69jcfhnmknvffwmfvlvnccatqwfjcyh0nlfc6gh5scta2yzg": "CoinBase", "addr1v9u7va2sktlnz8dp3qadpnxxlv4m03672jy6elmntlxxs7q9nnwl9": "CoinBase", "addr1vydqq7fww4sga05jvtfckw3z9z8n8n2zxj0fyelvdl86acqhd9l70": "CoinBase", - "addr1wy49natatgz5swjenvvqatwn48uj5p0lvw86uhvjjuth8xs2yr9fw": "DripDropz", "addr1w80ptp0qgmcklhmeweesqgeurtlma8fsxsr9dt8au30fzss0czhl9": "Indigo Protocol (Stability pool)", "addr1w849xkxel6pvc7kcmc88dd82hkz32fjq3ega42wchd93xlgqxxpv5": "Indigo Protocol (CDP creator)", "addr1w89s3lfv7gkugker5llecq6x3k2vjvfnvp4692laeqe6w6s93vj3j": "Explosif (Direct sale)", @@ -24,6 +23,7 @@ "addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4": "Wingriders (Request)", "addr1wxvd7wcq59gqljmhm2s9yp2slvygljfr8xtc3wykx7uaukgt8lqh6": "Minswap (Harvest v1)", "addr1wxwl25gyxf4ryexcq02yakr389vp68y39cnt4rnnhsu9utcjfhaef": "Minswap (MINt staking liquidity)", + "addr1wy49natatgz5swjenvvqatwn48uj5p0lvw86uhvjjuth8xs2yr9fw": "DripDropz", "addr1wycwqtlc2a3f3w4axqwwukyj34anyqmy404w24kydc70gtg5w4elq": "MELD (staking 2)", "addr1wypr0np3xatwhddulsnj3aaac65qg768zgs2xpd2xuaj0zscmvh0n": "Wingriders (Farm/Voting)", "addr1z8nvjzjeydcn4atcd93aac8allvrpjn7pjr2qsweukpnay0ycn5y6v5mjqqcs9xqa24kv5qk73tqsf3ufrtvxh9kts0qveyg6l": "Wingriders (Pool payment credential)", @@ -39,15 +39,49 @@ "addr1zxj47sy4qxlktqzmkrw8dahe46gtv8seakrshsqz26qnvzypw288a4x0xf8pxgcntelxmyclq83s0ykeehchz2wtspksr3q9nx": "jpg.store (Offers)", "addr1zyq0kyrml023kwjk8zr86d5gaxrt5w8lxnah8r6m6s4jp4g3r6dxnzml343sx8jweqn4vn3fz2kj8kgu9czghx0jrsyqqktyhv": "MuesliSwap (Partial Match Order)" }, + // Known metadata labels + "labels": { + "61284": "Catalyst", + "61285": "Catalyst Sig", + "674": "Message", + "914425": "Indigo SP Reward" + }, + // Policies to mute + "muted_policies": [ + "0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913", + "026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a570", + "0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1", + "13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f", + "24b458412c2a7f9acb9c53c7ec4325b36806912ed56d2f91bfcf4d26", + "2f2e0404310c106e2a260e8eb5a7e43f00cff42c667489d30e179816", + "2fccae8bc1c8553a2185b2e77ccdea22f2e1d6e87beb80ef4eaf8cce", + "408f13b240f57c3473b5727a68a88c50c1b6bb15c0c10912008dc59e", + "5817c34e5702473304f3cf676299176d3824e55b8c0bfa94830429fd", + "636c06ed152e70e9a1240da585a2841c15e4c3174044ca9a62cadab2", + "72c8ee38fc1adfc5db49f7384bd64d41e9b9ce46ec11ba9a292e5d02", + "8a7b0a43a169218fb66996c3945f53d7712eae9e31db193adb55663f", + "909133088303c49f3a30f1cc8ed553a73857a29779f6c6561cd8093f", + "97da12de04a6b527cc3b3469c5e5485cf258dfd1021f12e728f2e714", + "af3d70acf4bd5b3abb319a7d75c89fb3e56eafcdd46b2e9b57a2557f", + "d195ca7db29f0f13a00cac7fca70426ff60bad4e1e87d3757fae8484", + "de9b756719341e79785aa13c164e7fe68c189ed04d61c9876b2fe53f", + "e3455f2715338b454fb853442f72dc03b98396854f97510027fe22ff", + "e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86", + "e8a447d4e19016ca2aa74d20b4c4de87adb1f21dfb5493bf2d7281a6", + "f66d78b4a3cb3d37afa0ec36461e51ecbde00f26c8f0a68f94b69880", + "21ca2902ad0406bc2ce361ad91157b3542544d86d4e3d3e3c43f1763", + "2960fe7a50e78948eb7219079c39b8169e34a4464a3f1aea9328d87c" + ], // Known policies "policies": { - "0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913": "Sundaeswap", + "0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913": "Sundaeswap LP", "026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a570": "Wingriders Factory/Liquidity token v1", "0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1": "Minswap LP NFT 2", "13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f": "Minswap LP NFT 2", "21ca2902ad0406bc2ce361ad91157b3542544d86d4e3d3e3c43f1763": "VyFI NFT 1", "24b458412c2a7f9acb9c53c7ec4325b36806912ed56d2f91bfcf4d26": "INDY staking NFT", "2960fe7a50e78948eb7219079c39b8169e34a4464a3f1aea9328d87c": "VyFI NFT 2", + "29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6": "Minswap policy", "2f2e0404310c106e2a260e8eb5a7e43f00cff42c667489d30e179816": "Minswap NFT ?", "2fccae8bc1c8553a2185b2e77ccdea22f2e1d6e87beb80ef4eaf8cce": "INDY Gov NFT", "408f13b240f57c3473b5727a68a88c50c1b6bb15c0c10912008dc59e": "INDY iBTC mint NFT", @@ -57,6 +91,7 @@ "636c06ed152e70e9a1240da585a2841c15e4c3174044ca9a62cadab2": "NFT test", "708f5e6d597fc038d09a738d7be32edd6ea779d6feb32a53668d9050": "INDY CDP NFT", "72c8ee38fc1adfc5db49f7384bd64d41e9b9ce46ec11ba9a292e5d02": "NFT test", + "869fc72c11977e4be3e8e1cc63cca008a925886332795c9601f965ca": "USDC policy", "8a7b0a43a169218fb66996c3945f53d7712eae9e31db193adb55663f": "NFT test", "909133088303c49f3a30f1cc8ed553a73857a29779f6c6561cd8093f": "MuesliSwap NFT Policy v2", "97da12de04a6b527cc3b3469c5e5485cf258dfd1021f12e728f2e714": "INDY IASSET NFT", @@ -67,34 +102,9 @@ "e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86": "Minswap NFT", "e8a447d4e19016ca2aa74d20b4c4de87adb1f21dfb5493bf2d7281a6": "Sundae scooper", "f66d78b4a3cb3d37afa0ec36461e51ecbde00f26c8f0a68f94b69880": "Indigo", - "fd0d72fafee1d230a74c31ac503a192abd5b71888ae3f94128c1e634": "INDY staking NFT" + "fd0d72fafee1d230a74c31ac503a192abd5b71888ae3f94128c1e634": "INDY staking NFT", + "9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77": "Sundae policy", }, - // Policies to mute - "muted_policies": [ - "0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913", - "026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a570", - "0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1", - "13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f", - "24b458412c2a7f9acb9c53c7ec4325b36806912ed56d2f91bfcf4d26", - "2f2e0404310c106e2a260e8eb5a7e43f00cff42c667489d30e179816", - "2fccae8bc1c8553a2185b2e77ccdea22f2e1d6e87beb80ef4eaf8cce", - "408f13b240f57c3473b5727a68a88c50c1b6bb15c0c10912008dc59e", - "5817c34e5702473304f3cf676299176d3824e55b8c0bfa94830429fd", - "636c06ed152e70e9a1240da585a2841c15e4c3174044ca9a62cadab2", - "72c8ee38fc1adfc5db49f7384bd64d41e9b9ce46ec11ba9a292e5d02", - "8a7b0a43a169218fb66996c3945f53d7712eae9e31db193adb55663f", - "909133088303c49f3a30f1cc8ed553a73857a29779f6c6561cd8093f", - "97da12de04a6b527cc3b3469c5e5485cf258dfd1021f12e728f2e714", - "af3d70acf4bd5b3abb319a7d75c89fb3e56eafcdd46b2e9b57a2557f", - "d195ca7db29f0f13a00cac7fca70426ff60bad4e1e87d3757fae8484", - "de9b756719341e79785aa13c164e7fe68c189ed04d61c9876b2fe53f", - "e3455f2715338b454fb853442f72dc03b98396854f97510027fe22ff", - "e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86", - "e8a447d4e19016ca2aa74d20b4c4de87adb1f21dfb5493bf2d7281a6", - "f66d78b4a3cb3d37afa0ec36461e51ecbde00f26c8f0a68f94b69880", - "21ca2902ad0406bc2ce361ad91157b3542544d86d4e3d3e3c43f1763", - "2960fe7a50e78948eb7219079c39b8169e34a4464a3f1aea9328d87c" - ], // Known script hashes "scripts": { "00fb107bfbd51b3a5638867d3688e986ba38ff34fb738f5bd42b20d5": "MuesliSwap (Partial Match Order)", @@ -124,12 +134,5 @@ "e4d2fb0b8d275852103fd75801e2c7dcf6ed3e276c74cabadbe5b8b6": "Indigo Protocol (CDP)", "e6c90a5923713af5786963dee0fdffd830ca7e0c86a041d9e5833e91": "Wingriders (Pool payment credential)", "ea5358d9fe82cc7ad8de0e76b4eabd851526408e51daa9d8bb4b137d": "Indigo Protocol (CDP creator)" - }, - // Known metadata labels - "labels": { - "674": "Message", - "61284": "Catalyst", - "61285": "Catalyst Sig", - "914425": "Indigo SP Reward" } } \ No newline at end of file