
    %fj<                    p   d dl m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 d dl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 g dZh dZ ed           G d d                      ZdddFdZdGdZdHdZdIdZdJd#ZdKd'Z dLd*Z!dMd-Z"dNd0Z#dOd2Z$dPd4Z%d5d6d7dQd:Z&dRd<Z'dSd>Z(d5d?dTdCZ)dUdEZ*d5S )V    )annotations)	dataclassfield)DecimalInvalidOperation)
Connection)record_audit_event)create_crypto_asset)calculate_crypto_holdingscreate_initial_holding_snapshot)record_crypto_transfer)	stable_idutc_now)create_alert)zADA CardanoAmpzAvalanche AVAXzBitcoin BTC	ChainlinkDOGEzDecentraland MANAzEthereum ETHzHIGH HighstreetzIOTA IOTz
LUNA TerrazLUNC Terra ClassicNETVRzNuCypher NUzOx ZRXzPolygon MATICz
Ripple XRPzSAND The SandboxSAROSSKYz
SOL SolanaSundaezUSTC Terra Classic>   
crypto_buymanual_adjustmentinitial_snapshot_additionT)frozenc                  b    e Zd ZU ded<   ded<   dZded<   dZded<    ee          Zd	ed
<   dS )CryptoManageResultstrasset_id	wallet_idN
str | None
holding_idtransaction_id)default_factoryz	list[str]warnings)	__name__
__module____qualname____annotations__r"   r#   r   listr%        #src/jarvis_finance/crypto/manage.pyr   r   +   sd         MMMNNN!J!!!!!%N%%%%%555H555555r,   r   quantity
field_namevaluer   r0   returnr   c               6   t          |                                           }|st          | d          	 t          |          }n,# t          t          f$ r}t          | d          |d }~ww xY w|                                st          | d          |S )Nz is requiredz must be a Decimal stringz must be finite)r   strip
ValueErrorr   r   	is_finite)r1   r0   textdecexcs        r-   parse_decimal_textr:   4   s    u::D 6J444555Ldmmj) L L LJAAABBKL==?? 9J777888Js   A A0A++A0c                "    t          | d          S )Nf)format)r1   s    r-   decimal_textr>   A   s    %r,   confirmboolNonec                (    | st          d          d S )Nz*explicit confirm is required before saving)r5   )r?   s    r-   _require_confirmrC   E   s&     GEFFFG Gr,   effective_datec                
   t          |                                           }|st          d          |                    d          }t	          |          dk    st          d |D                       st          d          |S )Nzdate is required-   c              3  >   K   | ]}|                                 V  d S )N)isdigit).0parts     r-   	<genexpr>z _require_date.<locals>.<genexpr>P   s*      !C!CT$,,..!C!C!C!C!C!Cr,   zdate must be ISO YYYY-MM-DD)r   r4   r5   splitlenall)rD   r7   partss      r-   _require_daterQ   J   s    ~$$&&D -+,,,JJsOOE
5zzQc!C!CU!C!C!CCC6777Kr,   connr   r    c                    t          |                                          }|st          d          |                     d|f                                          }|t          d          |S )Nzwallet is requiredz6SELECT wallet_id FROM crypto_wallets WHERE wallet_id=?zwallet not found)r   r4   r5   executefetchone)rR   r    rows      r-   _require_walletrW   U   sn    I$$&&I /-...
,,OR[Q]
^
^
g
g
i
iC
{+,,,r,   	coin_namesymboltuple[str, str]c                    t          |                                           } t          |                                                                          }| st          d          |st          d          | |fS )Nzcoin name is requiredzsymbol is required)r   r4   upperr5   )rX   rY   s     r-   _require_coin_fieldsr]   _   su    I$$&&I[[  &&((F 20111 /-...fr,   notereasonc               t    t          | pd                                          } | st          d|           | S )N znote is required for )r   r4   r5   )r^   r_   s     r-   _require_noterb   i   sA    tzr??  ""D ;999:::Kr,   coingecko_idr!   c                   |rE|                      d|                                f                                          }|r|d         S |                      d||f                                          }|r|d         nd S )Nz7SELECT asset_id FROM crypto_assets WHERE coingecko_id=?r   z]SELECT asset_id FROM crypto_assets WHERE lower(coin_name)=lower(?) AND upper(symbol)=upper(?))rT   r4   rU   )rR   rX   rY   rc   rV   s        r-   _find_assetre   p   s     #llTWcWiWiWkWkVmnnwwyy 	#z?"
,,g	F  hjj  "+3z??t+r,   coingecko_statustuple[str, list[str]]c                  g }|r(|                                 r|                                 nd }t          | |||          }|r|}	nt          | ||||          }	|s|                    d           |dv rS|dk    rdnd}
t	          | ddd	|	|
d
|||d|	  	         |                                  |
|vr|                    |
           |	|fS )N)rX   rY   rc   )rX   rY   rc   notesmissing_coingecko_id>   	uncertainmissing_confirmedrk   "crypto_coingecko_mapping_uncertainwarnungcryptocrypto_assetz9Crypto asset CoinGecko mapping needs manual confirmation.)rY   rX   rf   prioritycategoryentity_type	entity_idrule_idmessageevidencefingerprint)r4   re   r
   appendr   commit)rR   rX   rY   rc   rf   r^   r%   cgexistingr   rules              r-   _ensure_assetr   |   s'    H!-	P,2D2D2F2F	P					DB49VRTUUUH n&ty^`hlmmm 0.///===7G;7V7V33\r&O &YTdee(
	
 
	
 
	
 
	
 	xOOD!!!Xr,   r   c                   t          |           }|j                            ||f          }|r|j        nt	          d          S )N0)r   wallet_holdingsgetr.   r   )rR   r    r   resultholdings        r-   current_wallet_asset_quantityr      sC    &t,,F$(()X)>??G&87GCLL8r,   deltac               ,   |dk    rt          d          t                      }t          |          }t          dd||t	          |          ||          }|dk     r|nd }	|dk    r|nd }
|                     d||t	          |          |	|
|||f           |S )Nr   z(manual adjustment delta must not be zerocryptotxr   ak  
        INSERT INTO crypto_transactions(
            crypto_transaction_id, transaction_type, asset_id, quantity,
            from_wallet_id, to_wallet_id, transaction_datetime, source,
            confirmation_status, parse_confidence, notes, created_at
        ) VALUES (?, 'manual_adjustment', ?, ?, ?, ?, ?, 'manual_dashboard', 'confirmed', 1, ?, ?)
        )r5   r   absr   r>   rT   )rR   r   r    r   rD   r^   nowqtytx_idfrom_wallet_idto_wallet_ids              r-   %_insert_manual_adjustment_transactionr      s     zzCDDD
))C
e**Cj"5xLY^L_L_aoqtuuE"'!))YYN %		99tLLL	 
,s++^\>[_ade	 	 	 Lr,   Nselected)rc   rf   quantity_textoperation_typec       
           t          |           |t          vrt          d          |dk    rt          d          t          |          }t	          | |          }t          ||          \  }}t          |          }|dk    rt          d          |dk    rt          |d          }n%t          |pd          	                                pd	}t          | |||	|
|
          \  }}|                     d||f                                          }|dk    r;|rt          d          t          | |||d|||          }t          ||||          S t          | ||          }t!          | |||||          }||z   }t#          | ddd|||t%          |          d||t%          |          t%          |          d|dd
  
         |                                  t          ||||          S )Nz,unsupported crypto management operation typer   zucrypto_buy requires the dedicated ledger buy workflow; use manual_adjustment or initial_snapshot_addition in this MVPr   quantity must be > 0r   r_   ra   z manual initial snapshot addition)rX   rY   rc   rf   r^   zNSELECT crypto_holding_id FROM crypto_holdings WHERE asset_id=? AND wallet_id=?r   zTinitial snapshot addition would overwrite an existing holding; use manual_adjustmentverified)r   r    r.   verification_statuslast_verified_atlegacy_snapshot_dater^   )r   r    r"   r%   r    r   r   r    r   rD   r^   crypto_managecrypto_manual_adjustmentcrypto_transactionr   r    r.   r   r    r.   r   T	dashboard	sourceactionrt   ru   
old_values
new_valuesuser_text_note	confirmed
created_by)r   r    r#   r%   )rC   VALID_ADD_TYPESr5   rQ   rW   r]   r:   rb   r   r4   r   rT   rU   r   r   r   r   r	   r>   r{   )rR   rX   rY   r    r   rD   r   r^   r?   rc   rf   r.   r   r%   existing_holdingr"   beforer   afters                      r-   add_crypto_positionr      s    W_,,GHHH%%  Q  R  R  	R">22Ni00I,Y??Iv!-00H1}}/000,,,T*=>>>4:2$$&&L*L&ty^j  ~N  UY  Z  Z  ZHh||X	9  hjj  444 	usttt4 *+!/	
 	
 	

 "8yU_jrssss*49xXXXF1$U^fn  @N  UY  Z  Z  ZEXE)( (yl[aNbNbcc (yl[`NaNalx  zB  mC  mC  D  D    	KKMMMx9UZemnnnnr,   new_quantity_textc                   t          |           t          |          }t          | |          }t          |d          }t	          |d          }|dk     rt          d          |                     d|f                                          }|t          d          t          | ||	          }	||	z
  }
|	|
z   dk     rt          d
          t          | |||
||          }t          | ddd|||t          |	          d||t          |          t          |
          d|dd
  
         |	dk    r7||	z  t          d          k    s|dk    rt          | ddd|dd||dd	  	         |                                  t          |||          S )Nr   r   znew quantityr/   r   znew quantity must be >= 03SELECT asset_id FROM crypto_assets WHERE asset_id=?asset not foundr   negative holding blockedr   r   r   r   r   r   Tr   r   10hinweisro   crypto_manual_adjustment_reviewzVManual crypto adjustment should be reviewed because it materially changes the holding.)r   r    manual_adjustment_reviewrq   r   r    r#   )rC   rQ   rW   rb   r:   r5   rT   rU   r   r   r	   r>   r   r   r{   r   )rR   r   r    r   rD   r^   r?   new_quantityassetr   r   r   s               r-   adjust_crypto_positionr     s    W">22Ni00I&9:::D%&7NSSSLa4555LLNQYP[\\eeggE}*+++*49xXXXF6!E~34441$U^fk  }K  RV  W  W  WE)( (yl[aNbNbcc (yl[gNhNhs  AF  tG  tG  H  H    {{v->>,RSBSBS,5l"*CC2
	
 
	
 
	
 
	
 	KKMMMx9UZ[[[[r,   reduction_quantity_textc          	     
   t          |           t          |d          }|dk    rt          d          t          | ||          }||z
  }	|	dk     rt          d          t	          | ||t          |	          |||          S )Nzreduction quantityr/   r   zreduction quantity must be > 0r   r   )r   r    r   rD   r^   r?   )rC   r:   r5   r   r   r>   )
rR   r   r    r   rD   r^   r?   	reductioncurrentr   s
             r-   reduce_crypto_positionr   <  s     W"#:G[\\\IA~~9:::+DIPXYYYGY&La3444!&|44%   r,   )fee_quantity_textr   r   r   c          	     $   t          |           t          |           t          | |          }t          | |          }t          |pd                                          pd}|                     d|f                                          }	|	t          d          t          |          }
|
dk    rt          d          t          |pdd	          }|dk     rt          d
          t          | ||||
||          }t          |||          S )Nra   zmanual wallet transferr   r   r   r   r   zfee quantityr/   zfee quantity must be >= 0)r   r   r   r.   fee_quantityr^   r   )rC   rQ   rW   r   r4   rT   rU   r5   r:   r   r   )rR   r   r   r   r   rD   r^   r?   r   r   r.   r   r   s                r-   transfer_crypto_positionr   Y  s/    W.!!!$T>::N"466Ltzr??  "">&>DLLNQYP[\\eeggE}*+++!-00H1}}/000%&7&>3>ZZZLa4555"%!!  E x<X]^^^^r,   +dict[str, list[dict[str, str]] | list[str]]c                Z   d |                      d                                          D             }d |                      d                                          D             }d |                      d                                          D             }|||t          t                    dS )Nc                >    g | ]}|d          |d         |d         dS )r    wallet_namewallet_type)r    r   r   r+   rJ   rV   s     r-   
<listcomp>z1get_crypto_management_options.<locals>.<listcomp>  sC        +&s=7IZ]^kZlmm  r,   zeSELECT wallet_id, wallet_name, wallet_type FROM crypto_wallets WHERE is_active=1 ORDER BY wallet_namec                P    g | ]#}|d          |d         |d         |d         pdd$S )r   rX   rY   rc   ra   )r   rX   rY   rc   r+   r   s     r-   r   z1get_crypto_management_options.<locals>.<listcomp>  se        _3{3CsS[}nq  sA  oB  oH  FH  	I  	I  r,   zpSELECT asset_id, coin_name, symbol, coingecko_id FROM crypto_assets WHERE is_active=1 ORDER BY coin_name, symbolc           	     h    g | ]/}|d          |d         |d         |d         |d         |d         d0S )r   r    rX   rY   r   r.   )r   r    rX   rY   r   r.   r+   r   s     r-   r   z1get_crypto_management_options.<locals>.<listcomp>  s^         J[)[)(m}-J	
 	
  r,   a4  
            SELECT h.asset_id, h.wallet_id, a.coin_name, a.symbol, w.wallet_name, h.quantity
            FROM crypto_holdings h
            JOIN crypto_assets a ON a.asset_id=h.asset_id
            JOIN crypto_wallets w ON w.wallet_id=h.wallet_id
            ORDER BY a.coin_name, w.wallet_name
            )walletsassetsholdingsmanual_review_coin_labels)rT   fetchallr*    CRYPTO_MANUAL_REVIEW_COIN_LABELS)rR   r   r   r   s       r-   get_crypto_management_optionsr     s     <<  !H  I  I  R  R  T  T  G <<  !S  T  T  ]  ]  _  _  F  <<
 
 (**#  H( %)*J%K%K	  r,   )r1   r   r0   r   r2   r   )r1   r   r2   r   )r?   r@   r2   rA   )rD   r   r2   r   )rR   r   r    r   r2   r   )rX   r   rY   r   r2   rZ   )r^   r   r_   r   r2   r   )
rR   r   rX   r   rY   r   rc   r!   r2   r!   )rR   r   rX   r   rY   r   rc   r!   rf   r   r^   r!   r2   rg   )rR   r   r    r   r   r   r2   r   )rR   r   r   r   r    r   r   r   rD   r   r^   r   r2   r   )rR   r   rX   r   rY   r   r    r   r   r   rD   r   r   r   r^   r   r?   r@   rc   r!   rf   r   r2   r   )rR   r   r   r   r    r   r   r   rD   r   r^   r   r?   r@   r2   r   )rR   r   r   r   r    r   r   r   rD   r   r^   r   r?   r@   r2   r   )rR   r   r   r   r   r   r   r   r   r   rD   r   r^   r   r?   r@   r   r!   r2   r   )rR   r   r2   r   )+
__future__r   dataclassesr   r   decimalr   r   sqlite3r   jarvis_finance.audit.logr	   jarvis_finance.crypto.assetsr
   jarvis_finance.crypto.holdingsr   r   "jarvis_finance.crypto.transactionsr   jarvis_finance.imports.commonr   r   jarvis_finance.quality.alertsr   r   r   r   r:   r>   rC   rQ   rW   r]   rb   re   r   r   r   r   r   r   r   r   r+   r,   r-   <module>r      s   " " " " " " ( ( ( ( ( ( ( ( - - - - - - - -       7 7 7 7 7 7 < < < < < < e e e e e e e e E E E E E E < < < < < < < < 6 6 6 6 6 6$ $ $  4 SRR $6 6 6 6 6 6 6 6 9C 
 
 
 
 
 
   G G G G
            	, 	, 	, 	," " " "J9 9 9 9   P  $&@o @o @o @o @o @oF2\ 2\ 2\ 2\j   N %)#_ #_ #_ #_ #_ #_N! ! ! ! ! !r,   