o
    >h                     @   s   d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZm	Z	 d dl
mZ ddlmZmZ d dlmZ d dlZd dlZd dlZd dlZd dlZd dlZdd	lmZmZ dd
lmZmZ G dd deZG dd deZG dd deZ dS )    N)RegisterOptionsCallDetails)ApplicationErrorTransportLost)ApplicationSession   )unpack_uint256pack_uint256)time_ns   )hlhlval)sign_eip712_channel_closerecover_eip712_channel_closec                   @   sN   e Zd ZdZdddZedd Zdd Zd	d
 Zdd Z	dd Z
dd ZdS )	KeySeriesz}
    Data encryption key series with automatic (time-based) key rotation
    and key offering (to the XBR market maker).
    Nc                 C   s   t |tkrt|dksJ t |tkr|dksJ |du s*t |tkr(|dks*J |du s:t |tkr8|dks:J |du rB|dusL|durJ|du sLJ |du sVt|sVJ || _|| _|| _|| _d| _	|| _
d| _d| _d| _i | _dS )a  

        :param api_id: ID of the API for which to generate keys.
        :type api_id: bytes

        :param price: Price per key in key series.
        :type price: int

        :param interval: Interval in seconds after which to auto-rotate key.
        :type interval: int

        :param count: Number of encryption operations after which to auto-rotate key.
        :type count: int

        :param on_rotate: Optional user callback fired after key was rotated.
        :type on_rotate: callable
           r   N)typebyteslenintcallable_api_id_price	_interval_count_count_current
_on_rotate_id_key_box_archive)selfapi_idpriceintervalcount	on_rotate r'   t/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/site-packages/autobahn/xbr/_seller.py__init__7   s      $
zKeySeries.__init__c                 C   s   | j S )z
        Get current XBR data encryption key ID (of the keys being rotated
        in a series).

        :return: Current key ID in key series (16 bytes).
        :rtype: bytes
        )r   r!   r'   r'   r(   key_id\   s   	zKeySeries.key_idc                    s\   t |}| jdur"|  jd7  _| j| jkr"|  I dH  d| _| j|}| jd|fS )z
        Encrypt data with the current XBR data encryption key.

        :param payload: Application payload to encrypt.
        :type payload: object

        :return: The ciphertext for the encrypted application payload.
        :rtype: bytes
        Nr   r   cbor)cbor2dumpsr   r   _rotater   encryptr   )r!   payloaddata
ciphertextr'   r'   r(   r0   g   s   


zKeySeries.encryptc                 C   sx   t |tkrt|dksJ t |tkrt|dksJ | j| \}}tjtjj|tjj	d}|j
|tjj	d}|S )a  
        Encrypt a (previously used) XBR data encryption key with a buyer public key.

        :param key_id: ID of the data encryption key to encrypt.
        :type key_id: bytes

        :param buyer_pubkey: Buyer WAMP public key (Ed25519) to asymmetrically encrypt
            the data encryption key (selected by ``key_id``) against.
        :type buyer_pubkey: bytes

        :return: The ciphertext for the encrypted data encryption key.
        :rtype: bytes
        r       )encoder)r   r   r   r    naclpublic	SealedBox	PublicKeyencoding
RawEncoderr0   )r!   r+   buyer_pubkeykey_sendkey_boxencrypted_keyr'   r'   r(   encrypt_key}   s   zKeySeries.encrypt_keyc                 C      t  NNotImplementedErrorr*   r'   r'   r(   start      zKeySeries.startc                 C   rB   rC   rD   r*   r'   r'   r(   stop   rG   zKeySeries.stopc                    s   t d| _tjtjjj| _	tj| j	| _
| j	| j
f| j| j< | jjdtdddttj| jdttj| jdd | jrL| | I d H  d S d S )Nr   z4{tx_type} key "{key_id}" rotated [api_id="{api_id}"]z
XBR ROTATEmagentacolorr   )tx_typer+   r"   )osurandomr   r6   utilsrandomsecret	SecretBoxKEY_SIZEr   r   r    logdebugr   uuidUUIDr   r   r*   r'   r'   r(   r/      s   
zKeySeries._rotateNNN)__name__
__module____qualname____doc__r)   propertyr+   r0   rA   rF   rH   r/   r'   r'   r'   r(   r   1   s    
%

r   c                   @   s   e Zd Zdd ZdS )PayingChannelc                 C   sb   t |tkrt|dksJ t |tkr|dksJ t |tkr$|dks&J || _|| _|| _d S )Nr   r   )r   r   r   r   _adr_seq_balance)r!   adrseqbalancer'   r'   r(   r)      s   
zPayingChannel.__init__N)rZ   r[   r\   r)   r'   r'   r'   r(   r_      s    r_   c                   @   s~   e Zd ZdZdZdZdZdZdZdZ	dddZ
ed	d
 ZdddZdd Zdd Zdd Zdd Z	dddZdddZdS )SimpleSellerNr   r   r         c                 C   s   t |tkrt|dksJ d|t |tkrt|dks&J d||du s7t |tks7J d|t | _tj	| _
|| _d| _|| _tj|| _d| _| jj | _d| _|pdt| jj| _i | _d| _d| _d| _i | _i | _d| _d| _dS )a  

        :param market_maker_adr: Market maker public Ethereum address (20 bytes).
        :type market_maker_adr: bytes

        :param seller_key: Seller (delegate) private Ethereum key (32 bytes).
        :type seller_key: bytes

        :param provider_id: Optional explicit data provider ID. When not given, the seller delegate
            public WAMP key (Ed25519 in Hex) is used as the provider ID. This must be a valid WAMP URI part.
        :type provider_id: string
           z0market_maker_adr must be bytes[20], but got "{}"r4   z/seller delegate must be bytes[32], but got "{}"Nz0provider_id must be None or string, but got "{}"r   ) r   r   r   formatstrtxaiomake_loggerrU   rf   
STATE_NONE_state_market_maker_adr_xbrmm_config	_pkey_raweth_keyskeys
PrivateKey_pkey_acct
public_keyto_canonical_address_addr_caddr_provider_id	_channels_channelrb   ra   _keys	_keys_map_session_session_regs)r!   market_maker_adr
seller_keyprovider_idr'   r'   r(   r)      s*   &&"

zSimpleSeller.__init__c                 C   s   | j jS )z
        This seller delegate public Ethereum key.

        :return: Ethereum public key of this seller delegate.
        :rtype: bytes
        )rv   rx   r*   r'   r'   r(   rx     s   zSimpleSeller.public_keyc           	         s(  t  tkrt dkr jvsJ t tkrdksJ |du s/t |tkr-|dks/J |du s?t |tkr=|dks?J |du rG|dusQ|durO|du sQJ du sqt tkrmdd  D rmdd  D sqJ d fdd	}j |||d
}|j < j	j
d|d |S )a  
        Add a new (rotating) private encryption key for encrypting data on the given API.

        :param api_id: API for which to create a new series of rotating encryption keys.
        :type api_id: bytes

        :param price: Price in XBR token per key.
        :type price: int

        :param interval: Interval (in seconds) after which to auto-rotate the encryption key.
        :type interval: int

        :param count: Number of encryption operations after which to auto-rotate the encryption key.
        :type count: int
        r   r   Nc                 s       | ]	}t |tkV  qd S rC   r   rk   ).0kr'   r'   r(   	<genexpr>+      z#SimpleSeller.add.<locals>.<genexpr>c                 s   r   rC   r   )r   vr'   r'   r(   r   +  r   zZinvalid categories type (must be dict) or category key or value type (must both be string)c           	         s  | j }| j|< d}|rzqt d }j}td}j}jjd| |||d d ur1t	nd d d |dI d H }j
jdtddd	ttj|d
ttj d
ttd ur_td ndd dd	tt| td j
jd|d W d S  ty } z|jdkrj
d nj
  W Y d }~d S W Y d }~nd }~w ty   j
d Y d S    j
  Y |d8 }j
jd|d tdI d H  |sd S d S )N   l    d(	 A   zxbr.marketmaker.place_offer)privkeyr#   
categoriesexpirescopiesr   zh{tx_type} key "{key_id}" offered for {price} [api_id={api_id}, prefix="{prefix}", delegate="{delegate}"]z
XBR OFFER rI   rJ   rL        NZor    XBR)rM   r+   r"   r#   delegateprefixzoffer={offer})offerzwamp.error.no_such_procedurez-xbr.marketmaker.offer: procedure unavailable!z2TransportLost while calling xbr.marketmaker.offer!r   z6Failed to place offer for key! Retrying {retries}/5 ..)retries)r+   r   r
   rz   rN   rO   r|   r   callr	   rU   rV   r   rW   rX   rk   r   binasciib2a_hexdecoder   errorwarnfailurer   asynciosleep)	
key_seriesr+   r   
valid_fromr   	signaturer   r   er"   r   r   r#   r!   r'   r(   r&   -  sf   



&	

z#SimpleSeller.add.<locals>.on_rotate)r$   r%   r&   z#Created new key series {key_series})r   )r   r   r   r   r   dictrt   valuesr   rU   rV   )	r!   r"   r   r#   r$   r%   r   r&   r   r'   r   r(   add  s   &  $@=
zSimpleSeller.addc                    s`  t |tsJ d|| jtjtjfv sJ dtj| _|| _g | _	| j
jdt| jt| jjdd  d |d| jI dH | _| jsMtd| jd	 }t|tkr^t|d
ks`J tj|d| _d| j}|j| j|t dddI dH }| j	!| | j
jdt|j"d d| j}|j| j#|t dddI dH }| j	!| | j
jdt|j"d | j$% D ]	}|& I dH  q|dI dH | _'|d| jjI dH }t|d tkrt(|d |d< |d dkstdt)||d |d | j*|< tj+| _|d | _,t| j,tkrt(| j,| _,|d | _-| j
j.dt| jt/| j,t/| j-d |d S )z
        Start rotating keys and placing key offers with the XBR market maker.

        :param session: WAMP session over which to communicate with the XBR market maker.
        :type session: :class:`autobahn.wamp.protocol.ApplicationSession`
        z/session must be an ApplicationSession, was "{}"zseller already runningzRStart selling from seller delegate address {address} (public key 0x{public_key}..)N
   )addressrx   z)xbr.marketmaker.get_active_paying_channelzno active paying channel foundchannel_oidr   rL   zxbr.provider.{}.selldetails)details_arg)optionsz"Registered procedure "{procedure}")	procedurezxbr.provider.{}.close_channelzxbr.marketmaker.get_config*xbr.marketmaker.get_paying_channel_balance	remainingr   z0no off-chain balance remaining on paying channelrd   zvOk, seller delegate started [active paying channel {channel_oid} with remaining balance {remaining} at sequence {seq}])r   r   rd   )0
isinstancer   rj   ro   rf   rn   STATE_STOPPEDSTATE_STARTINGr   r   rU   rV   r   r{   r   r   rv   rx   r   r   rz   r~   	Exceptionr   r   r   rW   rX   _channel_oidr|   registersellr   appendr   close_channelr   r   rF   rq   r   r_   r}   STATE_STARTEDrb   ra   infor   )r!   sessionr   r   regr   paying_balancer'   r'   r(   rF   p  sT   


zSimpleSeller.startc                    s   | j tjfv sJ dtj| _ g }| j D ]}| }|| q| jr@| j	r=| j	
 r=| jD ]}| }|| q1d| _t|}zz|I dH  W n	   | j  Y W tj| _ d| _	ntj| _ d| _	w | jd dS )zF
        Stop rotating/offering keys to the XBR market maker.
        seller not runningNzOk, seller delegate stopped.)ro   rf   r   STATE_STOPPINGr   r   rH   r   r   r   is_attached
unregisterrl   gatherrU   r   r   r   )r!   dlr   dr   r'   r'   r(   rH     s0   

zSimpleSeller.stopc                    sN   | j tjfvrtd| jr| j std| jd| jd I dH }|S )a  
        Return current (off-chain) balance of paying channel:

        * ``amount``: The initial amount with which the paying channel was opened.
        * ``remaining``: The remaining amount of XBR in the paying channel that can be earned.
        * ``inflight``: The amount of XBR allocated to sell transactions that are currently processed.

        :return: Current paying balance.
        :rtype: dict
        r   z!market-maker session not attachedr   r   N)ro   rf   r   RuntimeErrorr   r   r   r~   )r!   r   r'   r'   r(   re     s   zSimpleSeller.balancec                    sn   t |tkrt|dkr|| jv sJ t |tksJ |dus"J | j| }||I dH \}}}|||fS )aG  
        Encrypt and wrap application payload for a given API and destined for a specific WAMP URI.

        :param api_id: API for which to encrypt and wrap the application payload for.
        :type api_id: bytes

        :param uri: WAMP URI the application payload is destined for (eg the procedure or topic URI).
        :type uri: str

        :param payload: Application payload to encrypt and wrap.
        :type payload: object

        :return: The encrypted and wrapped application payload: a tuple with ``(key_id, serializer, ciphertext)``.
        :rtype: tuple
        r   N)r   r   r   r   rk   r0   )r!   r"   urir1   	keyseriesr+   
serializerr3   r'   r'   r(   wrap  s   &

zSimpleSeller.wrapc              
   C   s  t |tkrt|dksJ dt |t |tkr!t|dks*J dt |t |tks9J dt |t |tkrEt|dksNJ dt |t |tks]J dt |t |tkrit|d	ksrJ d
t ||du st|tsJ d|| jkrt	dd| j
jt| j t| || jd kr| j  t	dd| j
jt| jd  t| || jkrt	dd| j
j| jd |t|}|| jkrt	dd| j
j| j|t|||||}||kr| jjd| j
jtt| tt| d t	dd| j
jt| j||||}	| j|t|||	d}
| jjd| j
jtdddttt|d  d! ddt|tt| t|jt|j d" |
S )#zI
        Called by a XBR Market Maker to close a paying channel.
        ri   z.market_maker_adr must be bytes[20], but was {}r   z)channel_oid must be bytes[16], but was {}z#channel_seq must be int, but was {}r4   z-channel_balance must be bytes[32], but was {}z)channel_is_final must be bool, but was {}r   z3marketmaker_signature must be bytes[65], but was {}N/details must be autobahn.wamp.types.CallDetailsz!xbr.error.unexpected_delegate_adrzS{}.sell() - unexpected market maker (delegate) address: expected 0x{}, but got 0x{}r    xbr.error.unexpected_channel_oidJ{}.sell() - unexpected paying channel address: expected 0x{}, but got 0x{} xbr.error.unexpected_channel_seqR{}.sell() - unexpected channel (after tx) sequence number: expected {}, but got {}r   $xbr.error.unexpected_channel_balanceJ{}.sell() - unexpected channel (after tx) balance: expected {}, but got {}t{klass}.sell()::XBRSIG[4/8] - EIP712 signature invalid: signer_address={signer_address}, delegate_adr={delegate_adr}klasssigner_addressdelegate_adrxbr.error.invalid_signatureO{}.sell()::XBRSIG[4/8] - EIP712 signature invalid or not signed by market maker)r   rd   re   is_finalr   z{klass}.close_channel() - {tx_type} closing channel {channel_oid}, closing balance {channel_balance}, closing sequence {channel_seq} [caller={caller}, caller_authid="{caller_authid}"]zXBR CLOSE  rI   rJ   r   r   )r   rM   channel_balancechannel_seqr   callercaller_authid)!r   r   r   rj   r   boolr   r   rp   r   	__class__rZ   r   r   r   r~   r   leavera   r   rb   r   rU   r   r   r   rr   rz   r	   rV   rk   r   r   )r!   r   r   r   r   channel_is_finalmarketmaker_signaturer   r   seller_signaturereceiptr'   r'   r(   r      sd   ****
&
*



	zSimpleSeller.close_channelc
                 C   s  t |tkrt|dksJ dt |tkrt|dks J dt |tkr,t|dks0J dt |tkr<t|dks@J dt |tksJJ dt |tkrVt|dks_J d	t |t |tkrkt|dkstJ d
t |t |tkrt|dksJ d|	du st|	tsJ dt|}t|}|| jkrt	dd| j
jt| j t| || jvrt	dd| j
j|| j| }
|| jd kr| j  t	dd| j
jt| jd  t| || jd krt	dd| j
j| jd ||| j| krt	dd| j
j| j| |d}| jd }t| jd dd }| jd }t|||||||d|	}||krj| jjd | j
jtt| tt| d! t	d"d#| j
j|  jd7  _|  j|8  _|
||}t |tkrt|d$ksJ d%| j
j|t| j|||||| j| jd	}|| j||| j|| j|d&}| jjd'| j
jtd(d)d*tt j!|d+tt"t|d, d- d)d*tt"t| jd, d- d)d*t|	j#t|	j$tt| d.	 |S )/al  
        Called by a XBR Market Maker to buy a data encyption key. The XBR Market Maker here is
        acting for (triggered by) the XBR buyer delegate.

        :param market_maker_adr: The market maker Ethereum address. The technical buyer is usually the
            XBR market maker (== the XBR delegate of the XBR market operator).
        :type market_maker_adr: bytes of length 20

        :param buyer_pubkey: The buyer delegate Ed25519 public key.
        :type buyer_pubkey: bytes of length 32

        :param key_id: The UUID of the data encryption key to buy.
        :type key_id: bytes of length 16

        :param channel_oid: The on-chain channel contract address.
        :type channel_oid: bytes of length 16

        :param channel_seq: Paying channel sequence off-chain transaction number.
        :type channel_seq: int

        :param amount: The amount paid by the XBR Buyer via the XBR Market Maker.
        :type amount: bytes

        :param balance: Balance remaining in the payment channel (from the market maker to the
            seller) after successfully buying the key.
        :type balance: bytes

        :param signature: Signature over the supplied buying information, using the Ethereum
            private key of the market maker (which is the delegate of the marker operator).
        :type signature: bytes of length 65

        :param details: Caller details. The call will come from the XBR Market Maker.
        :type details: :class:`autobahn.wamp.types.CallDetails`

        :return: The data encryption key, itself encrypted to the public key of the original buyer.
        :rtype: bytes
        ri   zdelegate_adr must be bytes[20]r4   zbuyer_pubkey must be bytes[32]r   zkey_id must be bytes[16]zchannel_oid must be bytes[16]zchannel_seq must be intz)amount_paid must be bytes[32], but was {}z*post_balance must be bytes[32], but was {}r   zsignature must be bytes[65]Nr   z$xbr.error.unexpected_marketmaker_adrzH{}.sell() - unexpected market maker address: expected 0x{}, but got 0x{}zcrossbar.error.no_such_objectz{}.sell() - no key with ID "{}"r   r   r   r   r   r   r   r   verifying_chain_idverifying_contract_adrr   
market_oidFr   r   r   r   P   zC{}.sell() - unexpected sealed key computed (expected bytes[80]): {})r+   r   r<   
sealed_keyr   amountre   r   z{klass}.sell() - {tx_type} key "{key_id}" sold for {amount_earned} - balance is {balance} [caller={caller}, caller_authid="{caller_authid}", buyer_pubkey="{buyer_pubkey}"]z
XBR SELL  rI   rJ   rL   r   r   )r   rM   r+   amount_earnedre   r   r   r<   )%r   r   r   r   rj   r   r   r   rp   r   r   rZ   r   r   r   r   r~   r   r   ra   rb   rq   a2b_hexr   rU   r   r   rA   r   rr   rz   r   rW   rX   rk   r   r   )r!   r   r<   r+   r   r   r   re   r   r   r   current_block_numberr   r   r   r   r   r   r   r'   r'   r(   r   B  s    &   ** 
&


*


0


zSimpleSeller.sellrC   rY   )rZ   r[   r\   rU   r   rn   r   r   r   r   r)   r^   rx   r   rF   rH   re   r   r   r   r'   r'   r'   r(   rf      s&    
B

	ZA!
Brf   )!r   r   rN   rW   autobahn.wamp.typesr   r   autobahn.wamp.exceptionr   r   autobahn.wamp.protocolr   _utilr   r	   rl   r
   r-   rs   nacl.secretr6   
nacl.utilsnacl.publicutilr   r   _eip712_channel_closer   r   objectr   r_   rf   r'   r'   r'   r(   <module>   s*    
