Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ make tests
```

### Changelogs
**0.8.4**
* Added methods to SpotMarket, DerivativeMarket and BianaryOptionMarket to translate chain prices and quantities to human-readable format.

**0.8.3**
* Fix dependency issue in setup.py.

Expand Down
11 changes: 3 additions & 8 deletions examples/SendToInjective.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import json
import requests

import asyncio
import logging

from pyinjective.core.network import Network
from pyinjective.sendtocosmos import Peggo

import importlib.resources as pkg_resources
import pyinjective

async def main() -> None:
# select network: testnet, mainnet
network = Network.testnet()
Expand All @@ -27,8 +21,9 @@ async def main() -> None:

data = '{"@type": "/injective.exchange.v1beta1.MsgDeposit","sender": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku","subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000","amount": {"denom": "inj","amount": "1000000000000000000"}}'

import_peggo = pkg_resources.read_text(pyinjective, 'Peggo_ABI.json')
peggo_abi = json.loads(import_peggo)
with open("../pyinjective/Peggo_ABI.json") as pego_file:
peggo_data = pego_file.read()
peggo_abi = json.loads(peggo_data)

peggo_composer.sendToInjective(ethereum_endpoint=ethereum_endpoint, private_key=private_key, token_contract=token_contract,
receiver=receiver, amount=amount, maxFeePerGas=maxFeePerGas_Gwei, maxPriorityFeePerGas=maxPriorityFeePerGas_Gwei, data=data, peggo_abi=peggo_abi)
Expand Down
27 changes: 26 additions & 1 deletion pyinjective/core/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def price_to_chain_format(self, human_readable_value: Decimal) -> Decimal:

return extended_chain_formatted_value

def quantity_from_chain_format(self, chain_value: Decimal) -> Decimal:
return chain_value / Decimal(f"1e{self.base_token.decimals}")

def price_from_chain_format(self, chain_value: Decimal) -> Decimal:
decimals = self.base_token.decimals - self.quote_token.decimals
return chain_value * Decimal(f"1e{decimals}")

@dataclass(eq=True, frozen=True)
class DerivativeMarket:
id: str
Expand Down Expand Up @@ -92,6 +99,15 @@ def calculate_margin_in_chain_format(

return extended_chain_formatted_margin

def quantity_from_chain_format(self, chain_value: Decimal) -> Decimal:
return chain_value

def price_from_chain_format(self, chain_value: Decimal) -> Decimal:
return chain_value * Decimal(f"1e-{self.quote_token.decimals}")

def margin_from_chain_format(self, chain_value: Decimal) -> Decimal:
return chain_value * Decimal(f"1e-{self.quote_token.decimals}")

@dataclass(eq=True, frozen=True)
class BinaryOptionMarket:
id: str
Expand Down Expand Up @@ -148,4 +164,13 @@ def calculate_margin_in_chain_format(
quantized_margin = (margin // min_quantity_tick_size) * min_quantity_tick_size
extended_chain_formatted_margin = quantized_margin * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}")

return extended_chain_formatted_margin
return extended_chain_formatted_margin

def quantity_from_chain_format(self, chain_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal:
# Binary option markets do not have a base market to provide the number of decimals
decimals = 0 if special_denom is None else special_denom.base
return chain_value * Decimal(f"1e-{decimals}")

def price_from_chain_format(self, chain_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal:
decimals = self.quote_token.decimals if special_denom is None else special_denom.quote
return chain_value * Decimal(f"1e-{decimals}")
2 changes: 1 addition & 1 deletion pyinjective/sendtocosmos.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class Peggo:
def __init__(self, network: str):
self.network = network
def sendToInjective(self, ethereum_endpoint: str, private_key: str, token_contract: str, receiver: str, amount: int,
def sendToInjective(self, ethereum_endpoint: str, private_key: str, token_contract: str, receiver: str, amount: float,
maxFeePerGas: int, maxPriorityFeePerGas: int, peggo_abi: str, data: str, decimals=18):
if self.network == 'testnet':
peggy_proxy_address = "0xd2C6753F6B1783EF0a3857275e16e79D91b539a3"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
EMAIL = "achilleas@injectivelabs.com"
AUTHOR = "Injective Labs"
REQUIRES_PYTHON = ">=3.9"
VERSION = "0.8.3"
VERSION = "0.8.4"

REQUIRED = [
"aiohttp",
Expand Down
97 changes: 97 additions & 0 deletions tests/core/test_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ def test_convert_price_to_chain_format(self, inj_usdt_spot_market: SpotMarket):

assert (quantized_chain_format_value == chain_value)

def test_convert_quantity_from_chain_format(self, inj_usdt_spot_market: SpotMarket):
expected_quantity = Decimal("123.456")

chain_format_quantity = expected_quantity * Decimal(f"1e{inj_usdt_spot_market.base_token.decimals}")
human_readable_quantity = inj_usdt_spot_market.quantity_from_chain_format(chain_value=chain_format_quantity)

assert (expected_quantity == human_readable_quantity)

def test_convert_price_from_chain_format(self, inj_usdt_spot_market: SpotMarket):
expected_price = Decimal("123.456")

price_decimals = inj_usdt_spot_market.quote_token.decimals - inj_usdt_spot_market.base_token.decimals
chain_format_price = expected_price * Decimal(f"1e{price_decimals}")
human_readable_price = inj_usdt_spot_market.price_from_chain_format(chain_value=chain_format_price)

assert (expected_price == human_readable_price)



class TestDerivativeMarket:

Expand Down Expand Up @@ -76,6 +94,32 @@ def test_convert_margin_to_chain_format(self, btc_usdt_perp_market: DerivativeMa

assert (quantized_chain_format_value == chain_value)

def test_convert_quantity_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
expected_quantity = Decimal("123.456")

chain_format_quantity = expected_quantity
human_readable_quantity = btc_usdt_perp_market.quantity_from_chain_format(chain_value=chain_format_quantity)

assert (expected_quantity == human_readable_quantity)

def test_convert_price_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
expected_price = Decimal("123.456")

price_decimals = btc_usdt_perp_market.quote_token.decimals
chain_format_price = expected_price * Decimal(f"1e{price_decimals}")
human_readable_price = btc_usdt_perp_market.price_from_chain_format(chain_value=chain_format_price)

assert (expected_price == human_readable_price)

def test_convert_margin_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
expected_margin = Decimal("123.456")

price_decimals = btc_usdt_perp_market.quote_token.decimals
chain_format_margin = expected_margin * Decimal(f"1e{price_decimals}")
human_readable_margin = btc_usdt_perp_market.margin_from_chain_format(chain_value=chain_format_margin)

assert (expected_margin == human_readable_margin)

class TestBinaryOptionMarket:

def test_convert_quantity_to_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
Expand Down Expand Up @@ -211,3 +255,56 @@ def test_calculate_margin_for_sell_without_fixed_denom(self, first_match_bet_mar
quantized_chain_format_margin = quantized_margin * Decimal(f"1e18")

assert (quantized_chain_format_margin == chain_value)

def test_convert_quantity_from_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
original_quantity = Decimal("123.456789")
fixed_denom = Denom(
description="Fixed denom",
base=2,
quote=4,
min_quantity_tick_size=100,
min_price_tick_size=10000,
)

chain_formatted_quantity = original_quantity * Decimal(f"1e{fixed_denom.base}")

human_readable_quantity = first_match_bet_market.quantity_from_chain_format(
chain_value=chain_formatted_quantity, special_denom=fixed_denom
)

assert (original_quantity == human_readable_quantity)

def test_convert_quantity_from_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
original_quantity = Decimal("123.456789")

chain_formatted_quantity = original_quantity

human_readable_quantity = first_match_bet_market.quantity_from_chain_format(chain_value=chain_formatted_quantity)

assert (original_quantity == human_readable_quantity)

def test_convert_price_from_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
original_price = Decimal("123.456789")
fixed_denom = Denom(
description="Fixed denom",
base=2,
quote=4,
min_quantity_tick_size=100,
min_price_tick_size=10000,
)

chain_formatted_price = original_price * Decimal(f"1e{fixed_denom.quote}")

human_readable_price = first_match_bet_market.price_from_chain_format(
chain_value=chain_formatted_price, special_denom=fixed_denom
)

assert (original_price == human_readable_price)

def test_convert_price_from_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
original_price = Decimal("123.456789")
chain_formatted_price = original_price * Decimal(f"1e{first_match_bet_market.quote_token.decimals}")

human_readable_price = first_match_bet_market.price_from_chain_format(chain_value=chain_formatted_price)

assert (original_price == human_readable_price)