o
    Zh                     @   sx   d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlZd dl	m
Z
 d dlmZ G dd deZG dd	 d	eZdS )
    N)Enum)ListOptional)Document)
BaseLoaderc                   @   s\   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdS )BlockchainTypez(Enumerator of the supported blockchains.zeth-mainnetz
eth-goerlizeth-sepoliazeth-holeskyzpolygon-mainnetzpolygon-mumbaizpolygon-amoyzarb-mainnetzarb-sepoliazopt-mainnetzopt-sepoliazbase-mainnetzbase-sepoliazblast-mainnetzblast-sepoliazzksync-mainnetzzksync-sepoliazzora-mainnetzzora-sepoliaN)__name__
__module____qualname____doc__ETH_MAINNETZ
ETH_GOERLIZETH_SEPOLIAZETH_HOLESKYZPOLYGON_MAINNETZPOLYGON_MUMBAIZPOLYGON_AMOYZARB_MAINNETZARB_SEPOLIAZ
OP_MAINNETZ
OP_SEPOLIAZBASE_MAINNETZBASE_SEPOLIAZBLAST_MAINNETZBLAST_SEPOLIAZZKSYNC_MAINNETZZKSYNC_SEPOLIAZZORA_MAINNETZZORA_SEPOLIA r   r   f/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/document_loaders/blockchain.pyr      s*    r   c                   @   s~   e Zd ZdZejddddfdededed	ed
edee	 fddZ
dee fddZdedefddZededefddZdS )BlockchainDocumentLoadera9  Load elements from a blockchain smart contract.

    See supported blockchains here: https://python.langchain.com/v0.2/api_reference/community/document_loaders/langchain_community.document_loaders.blockchain.BlockchainType.html

    If no BlockchainType is specified, the default is Ethereum mainnet.

    The Loader uses the Alchemy API to interact with the blockchain.
    ALCHEMY_API_KEY environment variable must be set to use this loader.

    The API returns 100 NFTs per request and can be paginated using the
    startToken parameter.

    If get_all_tokens is set to True, the loader will get all tokens
    on the contract.  Note that for contracts with a large number of tokens,
    this may take a long time (e.g. 10k tokens is 100 requests).
    Default value is false for this reason.

    The max_execution_time (sec) can be set to limit the execution time
    of the loader.

    Future versions of this loader can:
        - Support additional Alchemy APIs (e.g. getTransactions, etc.)
        - Support additional blockchain APIs (e.g. Infura, Opensea, etc.)
    z	docs-demo FNcontract_addressblockchainTypeapi_key
startTokenget_all_tokensmax_execution_timec                 C   sb   || _ |j| _tjdp|| _|| _|| _|| _	| js t
dtd| j s/t
d| j  dS )au  

        Args:
            contract_address: The address of the smart contract.
            blockchainType: The blockchain type.
            api_key: The Alchemy API key.
            startToken: The start token for pagination.
            get_all_tokens: Whether to get all tokens on the contract.
            max_execution_time: The maximum execution time (sec).
        ZALCHEMY_API_KEYzAlchemy API key not provided.z^0x[a-fA-F0-9]{40}$zInvalid contract address N)r   valuer   osenvirongetr   r   r   r   
ValueErrorrematch)selfr   r   r   r   r   r   r   r   r   __init__?   s   z!BlockchainDocumentLoader.__init__returnc                 C   s  g }| j }t }	 d| j d| j d| j d| }t|}|jdkr-td|j |	 d }|s6nA|D ]}t
|}|d	 d
 }	| j| j|	d}
|t||
d q8| jsZn| |d jd
 }| jd urvt | | jkrvtdq
|std| j |S )NTzhttps://z.g.alchemy.com/nft/v2/z8/getNFTsForCollection?withMetadata=True&contractAddress=z&startToken=   z Request failed with status code ZnftsidtokenId)sourceZ
blockchainr#   )Zpage_contentmetadataz/Execution time exceeded the allowed time limit.z#No NFTs found for contract address )r   timer   r   r   requestsr   status_coder   jsonstrappendr   r   _get_next_tokenIdr%   r   RuntimeError)r   resultZcurrent_start_token
start_timeurlresponseitemsitemcontentr#   r%   r   r   r   load_   sP   




+
zBlockchainDocumentLoader.loadr#   c                 C   s   |  |}|dkrt|d}n|dkrt|dd  d}nt|}|d }|dkr:dt|dtt|d  d  S |dkrOd	t|dtt|d
  d  S t|S )Nhex_0x   hex_0xbf      0x0x0xbf   )_detect_value_typeintformatr+   len)r   r#   Z
value_typeZ	value_intr/   r   r   r   r-      s   
""z*BlockchainDocumentLoader._get_next_tokenIdc                 C   s.   t | trdS | drdS | drdS dS )NrB   r<   r7   r?   r9   )
isinstancerB   
startswith)r#   r   r   r   rA      s   


z+BlockchainDocumentLoader._detect_value_type)r   r	   r
   r   r   r   r+   boolr   rB   r   r   r   r6   r-   staticmethodrA   r   r   r   r   r   %   s0    
 :r   )r   r   r'   enumr   typingr   r   r(   Zlangchain_core.documentsr   Z)langchain_community.document_loaders.baser   r   r   r   r   r   r   <module>   s    