|
36 | 36 | from .types import ( |
37 | 37 | AddressLike, |
38 | 38 | ModifyLiquidityParams, |
| 39 | + PathKey, |
39 | 40 | PermitBatch, |
40 | 41 | PermitSingle, |
41 | 42 | PoolKey, |
@@ -1370,29 +1371,6 @@ def get_token_token_spot_price( |
1370 | 1371 | spot_price = 1 / spot_price |
1371 | 1372 | return spot_price |
1372 | 1373 |
|
1373 | | - def get_quote_exact_input_single( |
1374 | | - self, |
1375 | | - token0: str, |
1376 | | - token1: str, |
1377 | | - qty: int, |
1378 | | - fee: int = 500, |
1379 | | - tick_spacing: int = 10, |
1380 | | - hooks: str = ZERO_HOOK, |
1381 | | - hook_data: bytes = bytes(), |
1382 | | - ) -> int: |
1383 | | - """Quote for token to token single hop trades with an exact input.""" |
1384 | | - if token0 < token1: |
1385 | | - zero_for_one = True |
1386 | | - else: |
1387 | | - zero_for_one = False |
1388 | | - (token0, token1) = (token1, token0) |
1389 | | - pool_key = (token0, token1, fee, tick_spacing, hooks) |
1390 | | - # [0]=The output quote [1]=estimated gas units used for the swap |
1391 | | - quote_amount: int = self.quoter.functions.quoteExactInputSingle( |
1392 | | - (pool_key, zero_for_one, qty, hook_data) |
1393 | | - ).call()[0] |
1394 | | - return quote_amount |
1395 | | - |
1396 | 1374 | def get_pool_id(self, pool: PoolKey) -> HexBytes: |
1397 | 1375 | pool_data = eth_abi.abi.encode( |
1398 | 1376 | types=["address", "address", "uint24", "int24", "address"], |
@@ -1494,6 +1472,95 @@ def estimate_price_impact( |
1494 | 1472 | price_impact_real: float = price_impact_with_fees - fee_realised_percentage |
1495 | 1473 | return price_impact_real |
1496 | 1474 |
|
| 1475 | + def encode_path_keys_input( |
| 1476 | + self, |
| 1477 | + path: List[PoolKey], |
| 1478 | + currency_in: str, |
| 1479 | + ) -> List[PathKey]: |
| 1480 | + """ |
| 1481 | + Encodes a list of PoolKeys into the format expected by the quoter for multi-hop ExactInput quotes. |
| 1482 | + """ |
| 1483 | + encoded_path: List[PathKey] = [] |
| 1484 | + for pool_key in path: |
| 1485 | + currency_out: str = ( |
| 1486 | + pool_key.currency1 |
| 1487 | + if currency_in.lower() == pool_key.currency0.lower() |
| 1488 | + else pool_key.currency0 |
| 1489 | + ) |
| 1490 | + path_key: PathKey = PathKey( |
| 1491 | + currency_out, pool_key.fee, pool_key.tick_spacing, pool_key.hooks, b"" |
| 1492 | + ) |
| 1493 | + encoded_path.append(path_key) |
| 1494 | + currency_in = currency_out |
| 1495 | + return encoded_path |
| 1496 | + |
| 1497 | + def encode_path_keys_output( |
| 1498 | + self, |
| 1499 | + path: List[PoolKey], |
| 1500 | + currency_out: str, |
| 1501 | + ) -> List[PathKey]: |
| 1502 | + """ |
| 1503 | + Encodes a list of PoolKeys into the format expected by the quoter for multi-hop ExactOutput quotes. |
| 1504 | + """ |
| 1505 | + encoded_path: List[PathKey] = [] |
| 1506 | + for pool_key in reversed(path): |
| 1507 | + currency_in: str = ( |
| 1508 | + pool_key.currency1 |
| 1509 | + if currency_out.lower() == pool_key.currency0.lower() |
| 1510 | + else pool_key.currency0 |
| 1511 | + ) |
| 1512 | + path_key: PathKey = PathKey( |
| 1513 | + currency_in, pool_key.fee, pool_key.tick_spacing, pool_key.hooks, b"" |
| 1514 | + ) |
| 1515 | + encoded_path.insert(0, path_key) |
| 1516 | + currency_out = currency_in |
| 1517 | + return encoded_path |
| 1518 | + |
| 1519 | + # Quoter methods |
| 1520 | + # Read methods |
| 1521 | + def get_quote_exact_input_single( |
| 1522 | + self, |
| 1523 | + token0: str, |
| 1524 | + token1: str, |
| 1525 | + qty: int, |
| 1526 | + fee: int = 500, |
| 1527 | + tick_spacing: int = 10, |
| 1528 | + hooks: str = ZERO_HOOK, |
| 1529 | + hook_data: bytes = bytes(), |
| 1530 | + ) -> int: |
| 1531 | + """Quote for token to token single hop trades with an exact input.""" |
| 1532 | + if token0 < token1: |
| 1533 | + zero_for_one = True |
| 1534 | + else: |
| 1535 | + zero_for_one = False |
| 1536 | + (token0, token1) = (token1, token0) |
| 1537 | + pool_key = (token0, token1, fee, tick_spacing, hooks) |
| 1538 | + # [0]=The output quote [1]=estimated gas units used for the swap |
| 1539 | + quote_amount: int = self.quoter.functions.quoteExactInputSingle( |
| 1540 | + (pool_key, zero_for_one, qty, hook_data) |
| 1541 | + ).call()[0] |
| 1542 | + return quote_amount |
| 1543 | + |
| 1544 | + def get_quote_exact_input( |
| 1545 | + self, |
| 1546 | + token0: str, |
| 1547 | + token1: str, |
| 1548 | + qty: int, |
| 1549 | + path: List[PoolKey], |
| 1550 | + ) -> int: |
| 1551 | + """Quote for token to token multi-hop trades with an exact input.""" |
| 1552 | + # [0]=The output quote [1]=estimated gas units used for the swap |
| 1553 | + encoded_path = self.encode_path_keys_input(path, token0) |
| 1554 | + |
| 1555 | + quote_amount: int = self.quoter.functions.quoteExactInput( |
| 1556 | + ( |
| 1557 | + token0, |
| 1558 | + encoded_path, |
| 1559 | + qty, |
| 1560 | + ) |
| 1561 | + ).call()[0] |
| 1562 | + return quote_amount |
| 1563 | + |
1497 | 1564 | def get_quote_exact_output_single( |
1498 | 1565 | self, |
1499 | 1566 | token0: str, |
@@ -1524,6 +1591,25 @@ def get_quote_exact_output_single( |
1524 | 1591 | ).call()[0] |
1525 | 1592 | return quote_amount |
1526 | 1593 |
|
| 1594 | + def get_quote_exact_output( |
| 1595 | + self, |
| 1596 | + token0: str, |
| 1597 | + token1: str, |
| 1598 | + qty: int, |
| 1599 | + path: List[PoolKey], |
| 1600 | + ) -> int: |
| 1601 | + """Quote for token to token multi-hop trades with an exact output.""" |
| 1602 | + |
| 1603 | + encoded_path = self.encode_path_keys_output(path, token1) |
| 1604 | + quote_amount: int = self.quoter.functions.quoteExactOutput( |
| 1605 | + ( |
| 1606 | + token1, |
| 1607 | + encoded_path, |
| 1608 | + qty, |
| 1609 | + ) |
| 1610 | + ).call()[0] |
| 1611 | + return quote_amount |
| 1612 | + |
1527 | 1613 | # Swap functions |
1528 | 1614 | def _token_to_token_swap_input( |
1529 | 1615 | self, |
|
0 commit comments