Skip to content

Commit 40726ae

Browse files
authored
Merge pull request #245 from InjectiveLabs/feat/add_from_chain_value_translation
Feat/add from chain value translation
2 parents b8be53c + 9370531 commit 40726ae

File tree

7 files changed

+131
-11
lines changed

7 files changed

+131
-11
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ make tests
8787
```
8888

8989
### Changelogs
90+
**0.8.4**
91+
* Added methods to SpotMarket, DerivativeMarket and BianaryOptionMarket to translate chain prices and quantities to human-readable format.
92+
9093
**0.8.3**
9194
* Fix dependency issue in setup.py.
9295

examples/SendToInjective.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
import json
2-
import requests
3-
42
import asyncio
5-
import logging
63

74
from pyinjective.core.network import Network
85
from pyinjective.sendtocosmos import Peggo
96

10-
import importlib.resources as pkg_resources
11-
import pyinjective
12-
137
async def main() -> None:
148
# select network: testnet, mainnet
159
network = Network.testnet()
@@ -27,8 +21,9 @@ async def main() -> None:
2721

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

30-
import_peggo = pkg_resources.read_text(pyinjective, 'Peggo_ABI.json')
31-
peggo_abi = json.loads(import_peggo)
24+
with open("../pyinjective/Peggo_ABI.json") as pego_file:
25+
peggo_data = pego_file.read()
26+
peggo_abi = json.loads(peggo_data)
3227

3328
peggo_composer.sendToInjective(ethereum_endpoint=ethereum_endpoint, private_key=private_key, token_contract=token_contract,
3429
receiver=receiver, amount=amount, maxFeePerGas=maxFeePerGas_Gwei, maxPriorityFeePerGas=maxPriorityFeePerGas_Gwei, data=data, peggo_abi=peggo_abi)
File renamed without changes.

pyinjective/core/market.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ def price_to_chain_format(self, human_readable_value: Decimal) -> Decimal:
3434

3535
return extended_chain_formatted_value
3636

37+
def quantity_from_chain_format(self, chain_value: Decimal) -> Decimal:
38+
return chain_value / Decimal(f"1e{self.base_token.decimals}")
39+
40+
def price_from_chain_format(self, chain_value: Decimal) -> Decimal:
41+
decimals = self.base_token.decimals - self.quote_token.decimals
42+
return chain_value * Decimal(f"1e{decimals}")
43+
3744
@dataclass(eq=True, frozen=True)
3845
class DerivativeMarket:
3946
id: str
@@ -92,6 +99,15 @@ def calculate_margin_in_chain_format(
9299

93100
return extended_chain_formatted_margin
94101

102+
def quantity_from_chain_format(self, chain_value: Decimal) -> Decimal:
103+
return chain_value
104+
105+
def price_from_chain_format(self, chain_value: Decimal) -> Decimal:
106+
return chain_value * Decimal(f"1e-{self.quote_token.decimals}")
107+
108+
def margin_from_chain_format(self, chain_value: Decimal) -> Decimal:
109+
return chain_value * Decimal(f"1e-{self.quote_token.decimals}")
110+
95111
@dataclass(eq=True, frozen=True)
96112
class BinaryOptionMarket:
97113
id: str
@@ -148,4 +164,13 @@ def calculate_margin_in_chain_format(
148164
quantized_margin = (margin // min_quantity_tick_size) * min_quantity_tick_size
149165
extended_chain_formatted_margin = quantized_margin * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}")
150166

151-
return extended_chain_formatted_margin
167+
return extended_chain_formatted_margin
168+
169+
def quantity_from_chain_format(self, chain_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal:
170+
# Binary option markets do not have a base market to provide the number of decimals
171+
decimals = 0 if special_denom is None else special_denom.base
172+
return chain_value * Decimal(f"1e-{decimals}")
173+
174+
def price_from_chain_format(self, chain_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal:
175+
decimals = self.quote_token.decimals if special_denom is None else special_denom.quote
176+
return chain_value * Decimal(f"1e-{decimals}")

pyinjective/sendtocosmos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class Peggo:
77
def __init__(self, network: str):
88
self.network = network
9-
def sendToInjective(self, ethereum_endpoint: str, private_key: str, token_contract: str, receiver: str, amount: int,
9+
def sendToInjective(self, ethereum_endpoint: str, private_key: str, token_contract: str, receiver: str, amount: float,
1010
maxFeePerGas: int, maxPriorityFeePerGas: int, peggo_abi: str, data: str, decimals=18):
1111
if self.network == 'testnet':
1212
peggy_proxy_address = "0xd2C6753F6B1783EF0a3857275e16e79D91b539a3"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
1818
AUTHOR = "Injective Labs"
1919
REQUIRES_PYTHON = ">=3.9"
20-
VERSION = "0.8.3"
20+
VERSION = "0.8.4"
2121

2222
REQUIRED = [
2323
"aiohttp",

tests/core/test_market.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ def test_convert_price_to_chain_format(self, inj_usdt_spot_market: SpotMarket):
3939

4040
assert (quantized_chain_format_value == chain_value)
4141

42+
def test_convert_quantity_from_chain_format(self, inj_usdt_spot_market: SpotMarket):
43+
expected_quantity = Decimal("123.456")
44+
45+
chain_format_quantity = expected_quantity * Decimal(f"1e{inj_usdt_spot_market.base_token.decimals}")
46+
human_readable_quantity = inj_usdt_spot_market.quantity_from_chain_format(chain_value=chain_format_quantity)
47+
48+
assert (expected_quantity == human_readable_quantity)
49+
50+
def test_convert_price_from_chain_format(self, inj_usdt_spot_market: SpotMarket):
51+
expected_price = Decimal("123.456")
52+
53+
price_decimals = inj_usdt_spot_market.quote_token.decimals - inj_usdt_spot_market.base_token.decimals
54+
chain_format_price = expected_price * Decimal(f"1e{price_decimals}")
55+
human_readable_price = inj_usdt_spot_market.price_from_chain_format(chain_value=chain_format_price)
56+
57+
assert (expected_price == human_readable_price)
58+
59+
4260

4361
class TestDerivativeMarket:
4462

@@ -76,6 +94,32 @@ def test_convert_margin_to_chain_format(self, btc_usdt_perp_market: DerivativeMa
7694

7795
assert (quantized_chain_format_value == chain_value)
7896

97+
def test_convert_quantity_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
98+
expected_quantity = Decimal("123.456")
99+
100+
chain_format_quantity = expected_quantity
101+
human_readable_quantity = btc_usdt_perp_market.quantity_from_chain_format(chain_value=chain_format_quantity)
102+
103+
assert (expected_quantity == human_readable_quantity)
104+
105+
def test_convert_price_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
106+
expected_price = Decimal("123.456")
107+
108+
price_decimals = btc_usdt_perp_market.quote_token.decimals
109+
chain_format_price = expected_price * Decimal(f"1e{price_decimals}")
110+
human_readable_price = btc_usdt_perp_market.price_from_chain_format(chain_value=chain_format_price)
111+
112+
assert (expected_price == human_readable_price)
113+
114+
def test_convert_margin_from_chain_format(self, btc_usdt_perp_market: DerivativeMarket):
115+
expected_margin = Decimal("123.456")
116+
117+
price_decimals = btc_usdt_perp_market.quote_token.decimals
118+
chain_format_margin = expected_margin * Decimal(f"1e{price_decimals}")
119+
human_readable_margin = btc_usdt_perp_market.margin_from_chain_format(chain_value=chain_format_margin)
120+
121+
assert (expected_margin == human_readable_margin)
122+
79123
class TestBinaryOptionMarket:
80124

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

213257
assert (quantized_chain_format_margin == chain_value)
258+
259+
def test_convert_quantity_from_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
260+
original_quantity = Decimal("123.456789")
261+
fixed_denom = Denom(
262+
description="Fixed denom",
263+
base=2,
264+
quote=4,
265+
min_quantity_tick_size=100,
266+
min_price_tick_size=10000,
267+
)
268+
269+
chain_formatted_quantity = original_quantity * Decimal(f"1e{fixed_denom.base}")
270+
271+
human_readable_quantity = first_match_bet_market.quantity_from_chain_format(
272+
chain_value=chain_formatted_quantity, special_denom=fixed_denom
273+
)
274+
275+
assert (original_quantity == human_readable_quantity)
276+
277+
def test_convert_quantity_from_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
278+
original_quantity = Decimal("123.456789")
279+
280+
chain_formatted_quantity = original_quantity
281+
282+
human_readable_quantity = first_match_bet_market.quantity_from_chain_format(chain_value=chain_formatted_quantity)
283+
284+
assert (original_quantity == human_readable_quantity)
285+
286+
def test_convert_price_from_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
287+
original_price = Decimal("123.456789")
288+
fixed_denom = Denom(
289+
description="Fixed denom",
290+
base=2,
291+
quote=4,
292+
min_quantity_tick_size=100,
293+
min_price_tick_size=10000,
294+
)
295+
296+
chain_formatted_price = original_price * Decimal(f"1e{fixed_denom.quote}")
297+
298+
human_readable_price = first_match_bet_market.price_from_chain_format(
299+
chain_value=chain_formatted_price, special_denom=fixed_denom
300+
)
301+
302+
assert (original_price == human_readable_price)
303+
304+
def test_convert_price_from_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket):
305+
original_price = Decimal("123.456789")
306+
chain_formatted_price = original_price * Decimal(f"1e{first_match_bet_market.quote_token.decimals}")
307+
308+
human_readable_price = first_match_bet_market.price_from_chain_format(chain_value=chain_formatted_price)
309+
310+
assert (original_price == human_readable_price)

0 commit comments

Comments
 (0)