diff --git a/uniswap/types.py b/uniswap/types.py index a43c132..e58ee8b 100644 --- a/uniswap/types.py +++ b/uniswap/types.py @@ -35,7 +35,7 @@ def __repr__(self) -> str: return f"Tick info (liquidityGross: {self.liquidityGross}; liquidityNet: {self.liquidityNet}; feeGrowthOutside0X128: {self.feeGrowthOutside0X128}; feeGrowthOutside1X128: {self.feeGrowthOutside1X128!r})" @dataclass -class UniswapV4_PathKey: +class UniswapV4_path_key: # The lower currency of the pool, sorted numerically currency0 : Address # The higher currency of the pool, sorted numerically diff --git a/uniswap/uniswap4.py b/uniswap/uniswap4.py index 6344f62..a9193ff 100644 --- a/uniswap/uniswap4.py +++ b/uniswap/uniswap4.py @@ -17,7 +17,7 @@ Nonce, HexBytes, ) -from .types import AddressLike, UniswapV4_slot0, UniswapV4_position_info, UniswapV4_tick_info, UniswapV4_PathKey +from .types import AddressLike, UniswapV4_slot0, UniswapV4_position_info, UniswapV4_tick_info, UniswapV4_path_key from .token import ERC20Token from .exceptions import InvalidToken, InsufficientBalance from .util import ( @@ -210,7 +210,7 @@ def get_quote_exact_input( self, currency: AddressLike, # input token qty: int, - path : List[UniswapV4_PathKey], + path : List[UniswapV4_path_key], ) -> Any: """ :path is a swap route @@ -234,7 +234,7 @@ def get_quote_exact_output( self, currency: AddressLike, # input token qty: int, - path : List[UniswapV4_PathKey], + path : List[UniswapV4_path_key], ) -> Any: """ :path is a swap route @@ -384,6 +384,7 @@ def swap( qty: int, fee: int, tick_spacing: int, + hook_data : bytes, sqrt_price_limit_x96: int = 0, zero_for_one: bool = True, hooks: Union[AddressLike, str, None] = NOHOOK_ADDRESS, @@ -437,6 +438,7 @@ def initialize( fee: int, tick_spacing: int, sqrt_price_limit_x96: int, + hook_data : bytes, hooks: Union[AddressLike, str, None] = NOHOOK_ADDRESS, gas: Optional[Wei] = None, max_fee: Optional[Wei] = None, @@ -467,6 +469,7 @@ def initialize( { "key": pool_key, "sqrtPriceX96": sqrt_price_limit_x96, + "hookData": hook_data, } ), self._get_tx_params(gas = gas, max_fee = max_fee, priority_fee = priority_fee), @@ -476,10 +479,12 @@ def donate( self, currency0: ERC20Token, currency1: ERC20Token, - qty: int, + qty1: int, + qty2: int, fee: int, tick_spacing: int, sqrt_price_limit_x96: int, + hook_data : bytes, hooks: Union[AddressLike, str, None] = NOHOOK_ADDRESS, gas: Optional[Wei] = None, max_fee: Optional[Wei] = None, @@ -509,13 +514,15 @@ def donate( self.router.functions.donate( { "key": pool_key, - "sqrtPriceX96": sqrt_price_limit_x96, + "amount0": qty1, + "amount1": qty2, + "hookData": hook_data, } ), self._get_tx_params(gas = gas, max_fee = max_fee, priority_fee = priority_fee), ) - def modify_position( + def modify_liquidity( self, currency0: ERC20Token, currency1: ERC20Token, @@ -524,6 +531,8 @@ def modify_position( tick_spacing: int, tick_upper: int, tick_lower: int, + salt : int, + hook_data : bytes, hooks: Union[AddressLike, str, None] = NOHOOK_ADDRESS, gas: Optional[Wei] = None, max_fee: Optional[Wei] = None, @@ -550,17 +559,19 @@ def modify_position( "hooks": hooks, } - modify_position_params = { + modify_liquidity_params = { "tickLower": tick_lower, "tickUpper": tick_upper, "liquidityDelta": qty, + "salt": salt, } return self._build_and_send_tx( - self.router.functions.modifyPosition( + self.router.functions.modifyLiquidity( { "key": pool_key, "params": modify_position_params, + "hookData": hook_data, } ), self._get_tx_params(value=Wei(qty), gas = gas, max_fee = max_fee, priority_fee = priority_fee), @@ -568,8 +579,7 @@ def modify_position( def settle( self, - currency0: ERC20Token, - qty: int, + currency0: Union[AddressLike, str, None], gas: Optional[Wei] = None, max_fee: Optional[Wei] = None, priority_fee: Optional[Wei] = None, @@ -589,7 +599,7 @@ def settle( def take( self, - currency0: ERC20Token, + currency0: Union[AddressLike, str, None], to: AddressLike, qty: int, gas: Optional[Wei] = None, @@ -612,6 +622,56 @@ def take( self._get_tx_params(gas = gas, max_fee = max_fee, priority_fee = priority_fee), ) + def mint( + self, + currency0: Union[AddressLike, str, None], + id: int, + qty: int, + gas: Optional[Wei] = None, + max_fee: Optional[Wei] = None, + priority_fee: Optional[Wei] = None, + ) -> HexBytes: + """ + :Called by the user to net out some value owed to the user + :Can also be used as a mechanism for _free_ flash loans + """ + + return self._build_and_send_tx( + self.router.functions.mint( + { + "currency ": currency0, + "id ": id, + "amount ": qty, + } + ), + self._get_tx_params(gas = gas, max_fee = max_fee, priority_fee = priority_fee), + ) + + def burn( + self, + currency0: Union[AddressLike, str, None], + id: int, + qty: int, + gas: Optional[Wei] = None, + max_fee: Optional[Wei] = None, + priority_fee: Optional[Wei] = None, + ) -> HexBytes: + """ + :Called by the user to net out some value owed to the user + :Can also be used as a mechanism for _free_ flash loans + """ + + return self._build_and_send_tx( + self.router.functions.burn( + { + "currency ": currency0, + "id ": id, + "amount ": qty, + } + ), + self._get_tx_params(gas = gas, max_fee = max_fee, priority_fee = priority_fee), + ) + # ------ Wallet balance ------------------------------------------------------------ def get_eth_balance(self) -> Wei: """Get the balance of ETH for your address.""" @@ -715,8 +775,8 @@ def get_token(self, address: AddressLike, abi_name: str = "erc20") -> ERC20Token symbol = _symbol return ERC20Token(symbol, address, name, decimals) - def get_pool_id(self, currency0: AddressLike, currency1: AddressLike, fee : int, tickSpacing : int, hooks : Union[AddressLike, str, None] = NOHOOK_ADDRESS) -> bytes: - if int(currency0) > int(currency1): + def get_pool_id(self, currency0: str, currency1: str, fee : int, tickSpacing : int, hooks : Union[AddressLike, str, None] = NOHOOK_ADDRESS) -> bytes: + if int(currency0, 16) > int(currency1, 16): currency0 , currency1 = currency1 , currency0 pool_id = bytes(self.w3.solidity_keccak(["address", "address", "int24", "int24", "address"], [(currency0, currency1, fee, tickSpacing, hooks)])) return pool_id