-
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Conversion tool: added parser and merge parser for FTMScan explorer.
- Loading branch information
Showing
5 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
from . import bscscan, etherscan, hecoinfo, polygonscan, snowtrace | ||
from . import bscscan, etherscan, ftmscan, hecoinfo, polygonscan, snowtrace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# -*- coding: utf-8 -*- | ||
# (c) Nano Nano Ltd 2024 | ||
|
||
from typing import TYPE_CHECKING, Dict, List | ||
|
||
from ...bt_types import FileId | ||
from ..datamerge import DataMerge, ParserRequired | ||
from ..out_record import TransactionOutRecord | ||
from ..parsers.etherscan import etherscan_nfts, etherscan_tokens | ||
from ..parsers.ftmscan import WALLET, WORKSHEET_NAME, ftm_int, ftm_txns | ||
from .etherscan import INTERNAL_TXNS, NFTS, TOKENS, TXNS, _do_merge_etherscan | ||
|
||
STAKE_ADDRESSES: List[str] = [] | ||
|
||
if TYPE_CHECKING: | ||
from ..datafile import DataFile | ||
|
||
|
||
def merge_ftmscan(data_files: Dict[FileId, "DataFile"]) -> bool: | ||
# Do same merge as Etherscan | ||
merge = _do_merge_etherscan(data_files, STAKE_ADDRESSES) | ||
|
||
if merge: | ||
# Change Etherscan parsers to FTMScan | ||
if TOKENS in data_files: | ||
data_files[TOKENS].parser.worksheet_name = WORKSHEET_NAME | ||
for data_row in data_files[TOKENS].data_rows: | ||
if data_row.t_record: | ||
address = data_row.t_record.wallet[-abs(TransactionOutRecord.WALLET_ADDR_LEN) :] | ||
data_row.t_record.wallet = f"{WALLET}-{address}" | ||
|
||
if NFTS in data_files: | ||
data_files[NFTS].parser.worksheet_name = WORKSHEET_NAME | ||
for data_row in data_files[NFTS].data_rows: | ||
if data_row.t_record: | ||
address = data_row.t_record.wallet[-abs(TransactionOutRecord.WALLET_ADDR_LEN) :] | ||
data_row.t_record.wallet = f"{WALLET}-{address}" | ||
|
||
return merge | ||
|
||
|
||
DataMerge( | ||
"FTMScan fees & multi-token transactions", | ||
{ | ||
TXNS: {"req": ParserRequired.MANDATORY, "obj": ftm_txns}, | ||
TOKENS: {"req": ParserRequired.OPTIONAL, "obj": etherscan_tokens}, | ||
NFTS: {"req": ParserRequired.OPTIONAL, "obj": etherscan_nfts}, | ||
INTERNAL_TXNS: {"req": ParserRequired.OPTIONAL, "obj": ftm_int}, | ||
}, | ||
merge_ftmscan, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ | |
electrum, | ||
etherscan, | ||
exodus, | ||
ftmscan, | ||
ftx, | ||
gatehub, | ||
gemini, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# -*- coding: utf-8 -*- | ||
# (c) Nano Nano Ltd 2024 | ||
|
||
from decimal import Decimal | ||
from typing import TYPE_CHECKING | ||
|
||
from typing_extensions import Unpack | ||
|
||
from ...bt_types import TrType | ||
from ..dataparser import DataParser, ParserArgs, ParserType | ||
from ..out_record import TransactionOutRecord | ||
from .etherscan import _get_note | ||
|
||
if TYPE_CHECKING: | ||
from ..datarow import DataRow | ||
|
||
WALLET = "Fantom Chain" | ||
WORKSHEET_NAME = "FTMScan" | ||
|
||
|
||
def parse_ftmscan(data_row: "DataRow", _parser: DataParser, **_kwargs: Unpack[ParserArgs]) -> None: | ||
row_dict = data_row.row_dict | ||
data_row.timestamp = DataParser.parse_timestamp(int(row_dict["UnixTimestamp"])) | ||
|
||
if row_dict["Status"] != "": | ||
# Failed transactions should not have a Value_OUT | ||
row_dict["Value_OUT(FTM)"] = "0" | ||
|
||
if Decimal(row_dict["Value_IN(FTM)"]) > 0: | ||
if row_dict["Status"] == "": | ||
data_row.t_record = TransactionOutRecord( | ||
TrType.DEPOSIT, | ||
data_row.timestamp, | ||
buy_quantity=Decimal(row_dict["Value_IN(FTM)"]), | ||
buy_asset="FTM", | ||
wallet=_get_wallet(row_dict["To"]), | ||
note=_get_note(row_dict), | ||
) | ||
elif Decimal(row_dict["Value_OUT(FTM)"]) > 0: | ||
data_row.t_record = TransactionOutRecord( | ||
TrType.WITHDRAWAL, | ||
data_row.timestamp, | ||
sell_quantity=Decimal(row_dict["Value_OUT(FTM)"]), | ||
sell_asset="FTM", | ||
fee_quantity=Decimal(row_dict["TxnFee(FTM)"]), | ||
fee_asset="FTM", | ||
wallet=_get_wallet(row_dict["From"]), | ||
note=_get_note(row_dict), | ||
) | ||
else: | ||
data_row.t_record = TransactionOutRecord( | ||
TrType.SPEND, | ||
data_row.timestamp, | ||
sell_quantity=Decimal(row_dict["Value_OUT(FTM)"]), | ||
sell_asset="FTM", | ||
fee_quantity=Decimal(row_dict["TxnFee(FTM)"]), | ||
fee_asset="FTM", | ||
wallet=_get_wallet(row_dict["From"]), | ||
note=_get_note(row_dict), | ||
) | ||
|
||
|
||
def _get_wallet(address: str) -> str: | ||
return f"{WALLET}-{address.lower()[0 : TransactionOutRecord.WALLET_ADDR_LEN]}" | ||
|
||
|
||
def parse_ftmscan_internal( | ||
data_row: "DataRow", _parser: DataParser, **_kwargs: Unpack[ParserArgs] | ||
) -> None: | ||
row_dict = data_row.row_dict | ||
data_row.timestamp = DataParser.parse_timestamp(int(row_dict["UnixTimestamp"])) | ||
|
||
# Failed internal transaction | ||
if row_dict["Status"] != "0": | ||
return | ||
|
||
if Decimal(row_dict["Value_IN(FTM)"]) > 0: | ||
data_row.t_record = TransactionOutRecord( | ||
TrType.DEPOSIT, | ||
data_row.timestamp, | ||
buy_quantity=Decimal(row_dict["Value_IN(FTM)"]), | ||
buy_asset="FTM", | ||
wallet=_get_wallet(row_dict["TxTo"]), | ||
) | ||
elif Decimal(row_dict["Value_OUT(FTM)"]) > 0: | ||
data_row.t_record = TransactionOutRecord( | ||
TrType.WITHDRAWAL, | ||
data_row.timestamp, | ||
sell_quantity=Decimal(row_dict["Value_OUT(FTM)"]), | ||
sell_asset="FTM", | ||
wallet=_get_wallet(row_dict["From"]), | ||
) | ||
|
||
|
||
# Token and NFT transactions have the same header as Etherscan | ||
ftm_txns = DataParser( | ||
ParserType.EXPLORER, | ||
"FTMScan (FTM Transactions)", | ||
[ | ||
"Txhash", | ||
"Blockno", | ||
"UnixTimestamp", | ||
"DateTime (UTC)", | ||
"From", | ||
"To", | ||
"ContractAddress", | ||
"Value_IN(FTM)", | ||
"Value_OUT(FTM)", | ||
None, | ||
"TxnFee(FTM)", | ||
"TxnFee(USD)", | ||
"Historical $Price/FTM", | ||
"Status", | ||
"ErrCode", | ||
"Method", | ||
], | ||
worksheet_name=WORKSHEET_NAME, | ||
row_handler=parse_ftmscan, | ||
) | ||
|
||
DataParser( | ||
ParserType.EXPLORER, | ||
"FTMScan (FTM Transactions)", | ||
[ | ||
"Txhash", | ||
"Blockno", | ||
"UnixTimestamp", | ||
"DateTime (UTC)", | ||
"From", | ||
"To", | ||
"ContractAddress", | ||
"Value_IN(FTM)", | ||
"Value_OUT(FTM)", | ||
None, | ||
"TxnFee(FTM)", | ||
"TxnFee(USD)", | ||
"Historical $Price/FTM", | ||
"Status", | ||
"ErrCode", | ||
"Method", | ||
"PrivateNote", | ||
], | ||
worksheet_name=WORKSHEET_NAME, | ||
row_handler=parse_ftmscan, | ||
) | ||
|
||
ftm_int = DataParser( | ||
ParserType.EXPLORER, | ||
"FTMScan (FTM Internal Transactions)", | ||
[ | ||
"Txhash", | ||
"Blockno", | ||
"UnixTimestamp", | ||
"DateTime (UTC)", | ||
"ParentTxFrom", | ||
"ParentTxTo", | ||
"ParentTxFTM_Value", | ||
"From", | ||
"TxTo", | ||
"ContractAddress", | ||
"Value_IN(FTM)", | ||
"Value_OUT(FTM)", | ||
None, | ||
"Historical $Price/FTM", | ||
"Status", | ||
"ErrCode", | ||
"Type", | ||
], | ||
worksheet_name=WORKSHEET_NAME, | ||
row_handler=parse_ftmscan_internal, | ||
) | ||
|
||
DataParser( | ||
ParserType.EXPLORER, | ||
"FTMScan (FTM Internal Transactions)", | ||
[ | ||
"Txhash", | ||
"Blockno", | ||
"UnixTimestamp", | ||
"DateTime (UTC)", | ||
"ParentTxFrom", | ||
"ParentTxTo", | ||
"ParentTxFTM_Value", | ||
"From", | ||
"TxTo", | ||
"ContractAddress", | ||
"Value_IN(FTM)", | ||
"Value_OUT(FTM)", | ||
None, | ||
"Historical $Price/FTM", | ||
"Status", | ||
"ErrCode", | ||
"Type", | ||
"PrivateNote", | ||
], | ||
worksheet_name=WORKSHEET_NAME, | ||
row_handler=parse_ftmscan_internal, | ||
) |