meshtrade 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of meshtrade might be problematic. Click here for more details.

@@ -0,0 +1,7 @@
1
+ from .amount import new_amount
2
+ from .decimal_built_in_conversions import built_in_to_decimal, decimal_to_built_in
3
+ from .decimal_pb2 import Decimal
4
+ from .ledger_pb2 import Ledger
5
+ from .ledger import get_ledger_no_decimal_places
6
+ from .token_pb2 import Token
7
+ from .amount_pb2 import Amount
@@ -0,0 +1,84 @@
1
+ """
2
+ This module provides a factory function for creating Amount protobuf messages.
3
+ """
4
+
5
+ from decimal import ROUND_DOWN, Decimal
6
+
7
+ from .amount_pb2 import Amount
8
+ from .decimal_built_in_conversions import built_in_to_decimal, decimal_to_built_in
9
+ from .ledger import get_ledger_no_decimal_places
10
+ from .token_pb2 import Token
11
+
12
+
13
+ def new_amount(
14
+ value: Decimal,
15
+ token: Token,
16
+ precision_loss_tolerance: Decimal = Decimal("0.00000001")
17
+ ) -> Amount:
18
+ """Creates a new Amount, ensuring the value conforms to system-wide limits.
19
+
20
+ This function is the safe constructor for creating Amount protobuf messages.
21
+ While the underlying conversion from a Python `Decimal` to the protobuf's
22
+ `string` field is lossless, this function provides critical validation
23
+ to ensure the value adheres to constraints imposed by other downstream
24
+ systems (e.g., databases, other microservices with fixed-precision types).
25
+
26
+ Its primary operations are:
27
+
28
+ 1. **Validation:** It performs a serialization round-trip
29
+ (Python Decimal -> Protobuf Decimal -> Python Decimal) to simulate
30
+ how the value is stored and retrieved across the system. It then asserts
31
+ the value remains unchanged, guaranteeing it doesn't exceed the
32
+ precision limits of any consuming service.
33
+
34
+ 2. **Truncation:** It truncates the validated value to the exact number of
35
+ decimal places defined for the token's ledger, always rounding down to
36
+ prevent any inflation of values.
37
+
38
+ 3. **Construction:** It constructs and returns the final `Amount` message.
39
+
40
+ Args:
41
+ value: The numerical value of the amount as a Python `Decimal` object.
42
+ token: The `Token` protobuf message that defines the asset type
43
+ and its associated ledger.
44
+ precision_loss_tolerance: The maximum acceptable difference after the
45
+ validation round-trip. Since the string-based conversion is
46
+ lossless, any difference indicates a failure to conform to an
47
+ external system's parsing rules. Defaults to a small tolerance
48
+ for robustness.
49
+
50
+ Returns:
51
+ An `Amount` protobuf message containing the ledger-compliant, truncated
52
+ value and the specified token.
53
+
54
+ Raises:
55
+ AssertionError: If the input `value` changes during the validation
56
+ round-trip, indicating it exceeds the system's
57
+ representational limits and would be corrupted
58
+ downstream.
59
+ """
60
+
61
+ # Perform a serialization round-trip to validate the value against
62
+ # system-wide architectural constraints. This is a lossless operation
63
+ # in isolation, so any change reveals an incompatibility.
64
+ value_after_roundtrip = decimal_to_built_in(built_in_to_decimal(value))
65
+
66
+ # Confirm the value is perfectly representable within the system's limits.
67
+ # If the original value had too much precision for a downstream service to
68
+ # parse, it would change during the round-trip, and this would fail.
69
+ assert abs(value_after_roundtrip - value) \
70
+ <= precision_loss_tolerance, \
71
+ "value exceeds system's precision limits and would be corrupted"
72
+
73
+ # Truncate the validated value to the number of decimal places specified by the
74
+ # token's ledger. ROUND_DOWN ensures the value is never inflated.
75
+ truncated_value = value_after_roundtrip.quantize(
76
+ Decimal(10) ** -get_ledger_no_decimal_places(token.ledger),
77
+ rounding=ROUND_DOWN,
78
+ )
79
+
80
+ # Construct and return the final Amount protobuf message using the sanitized value.
81
+ return Amount(
82
+ token=token,
83
+ value=built_in_to_decimal(truncated_value),
84
+ )
@@ -0,0 +1,29 @@
1
+ import decimal
2
+
3
+ from .decimal_pb2 import Decimal
4
+
5
+
6
+ def built_in_to_decimal(decimal_value: decimal.Decimal) -> Decimal:
7
+ """
8
+ Converts an instance of the built-in decimal.Decimal type to an instance of the
9
+ financial Decimal protobuf type.
10
+
11
+ :param decimal_value: The decimal.Decimal object to convert.
12
+ :return: The converted financial Decimal protobuf object.
13
+ """
14
+
15
+ # Contruct and return resultant decimal object
16
+ return Decimal(
17
+ value=str(decimal_value),
18
+ )
19
+
20
+
21
+ def decimal_to_built_in(decimal_value: Decimal) -> decimal.Decimal:
22
+ """
23
+ Converts an instance of the financial Decimal protobuf type to an instance of the
24
+ built-in decimal.Decimal type.
25
+
26
+ :param decimal_value: The decimal_pb2.Decimal object to convert.
27
+ :return: The converted decimal.Decimal object.
28
+ """
29
+ return decimal.Decimal( decimal_value.value if decimal_value.value != "" else "0" )
@@ -0,0 +1,26 @@
1
+ from typing import Dict
2
+
3
+ from .ledger_pb2 import Ledger
4
+
5
+ _ledger_decimal_places: Dict[Ledger, int] = {
6
+ Ledger.LEDGER_STELLAR: 7,
7
+ Ledger.LEDGER_SA_STOCK_BROKERS: 2,
8
+ }
9
+
10
+ class UnsupportedLedgerError(Exception):
11
+ """Exception raised for unsupported Ledger values."""
12
+
13
+ def __init__(self, ledger: Ledger):
14
+ self.financial_business_day_convention = ledger
15
+ message = f"Unsupported Ledger: {ledger}"
16
+ super().__init__(message)
17
+
18
+
19
+ def get_ledger_no_decimal_places(ledger: Ledger) -> int:
20
+ """
21
+ Returns the number of decimal places supported by the given Ledger
22
+ """
23
+ if ledger in _ledger_decimal_places:
24
+ return _ledger_decimal_places[ledger]
25
+ else:
26
+ raise UnsupportedLedgerError(ledger)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshtrade
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Integration SDK for Mesh API Services
5
5
  Author-email: Bernard Bussy <bernard@meshtrade.co>
6
6
  License-Expression: LicenseRef-My-Custom-License
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.12
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
21
  Requires-Dist: grpcio<2.0,>=1.73.0
@@ -79,15 +79,18 @@ meshtrade/trading/spot/v1/service_pb2.pyi,sha256=f0P_1fXtk9qWMRztTmSyq5t9a2zq44I
79
79
  meshtrade/trading/spot/v1/spot_pb2.py,sha256=zXtfxzJdH_mfZpadjaIjLpg3rmBUi7sm_9i5-mvuVRc,1534
80
80
  meshtrade/trading/spot/v1/spot_pb2.pyi,sha256=DELXsprA9tDCE2Pn1I7J3qIVgYVEI8oJiT6BPIwrR2I,387
81
81
  meshtrade/type/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- meshtrade/type/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ meshtrade/type/v1/__init__.py,sha256=mN_HvUFZ1uxR6ETeLcxiGYtPluaUSk3Tx5LJMZJ3hrI,286
83
83
  meshtrade/type/v1/address_pb2.py,sha256=dRokCvBkbOIE_AxDfCtQnNUoFSNjZ8f9lFW2ii4yqQk,1795
84
84
  meshtrade/type/v1/address_pb2.pyi,sha256=A1PdvzCZpd-JKQhTwwQ3gz2Kw9mOkH3S1imSm78_4Uw,1107
85
+ meshtrade/type/v1/amount.py,sha256=iDaAEB0WpuFwU5qE_gY5XWgqD0x0Z131mrAf-S45x1A,3696
85
86
  meshtrade/type/v1/amount_pb2.py,sha256=ympMEAxoG95ElDB_l5fk5y0dTLi5gXgwtD25_8ZNobM,1855
86
87
  meshtrade/type/v1/amount_pb2.pyi,sha256=uI8D2Ch66e2hvzQCA5SARE8lrGdU_BYby__P_H-QwvY,749
87
88
  meshtrade/type/v1/contact_details_pb2.py,sha256=fKhg7lUMJqa6XyA_cVDCin-hDg1garQ3-xYQlnuxPs0,2007
88
89
  meshtrade/type/v1/contact_details_pb2.pyi,sha256=Wk9EFWI_rPuuOvPdKsW9Qo0_c8uNg61U-w__YwPQD9E,1292
90
+ meshtrade/type/v1/decimal_built_in_conversions.py,sha256=Cbxjp8kHJ7E74C4DdXup8uMvZofrwNaXTyIY3xa1iLU,913
89
91
  meshtrade/type/v1/decimal_pb2.py,sha256=kzcMQ9eaGUWZlv06K6XftteRwX3vvudwrsKqmA_bkcI,1509
90
92
  meshtrade/type/v1/decimal_pb2.pyi,sha256=8qhL7jqAhoYJNzTpEiEPKDSRAYSWgvKd8altyVLISFg,386
93
+ meshtrade/type/v1/ledger.py,sha256=psduzLQCIKvEj3rZBHWcsvq1ZjUh3Hb34ycd48TAcy0,743
91
94
  meshtrade/type/v1/ledger_pb2.py,sha256=8xJ_7ClfGDwRGImZerIA6D4Zdvdq6jQL0Ebv5XJUgc0,1747
92
95
  meshtrade/type/v1/ledger_pb2.pyi,sha256=r3emyUDafn9p3XTzwpnM0gzLiwrmgXYTp8GwZxw8_FM,801
93
96
  meshtrade/type/v1/token_pb2.py,sha256=48dMzVixXluV46B1Pqnfp-yLIeL0NYVg3ZzKQlX-ohc,1741
@@ -98,8 +101,8 @@ meshtrade/wallet/account/v1/account_pb2.py,sha256=Jh8Dnju5zktGXfzWY5HGrvq1iO82SN
98
101
  meshtrade/wallet/account/v1/account_pb2.pyi,sha256=GN2bT5Ld2B0KyQUmkDQjHfeXEjLSwfuIE2j70jSMIJE,382
99
102
  meshtrade/wallet/account/v1/service_pb2.py,sha256=djmoH_Hlld8RlZhtRxDS6Iw2wLwFoHhunExy9EQmbJc,8098
100
103
  meshtrade/wallet/account/v1/service_pb2.pyi,sha256=K0d1vjgzzKdGrluF9h2InzFu3-lMy6UQIUqAmb0xDl4,2819
101
- meshtrade-0.0.4.dist-info/licenses/LICENSE,sha256=7e68NmtCi6H_-e-fbQ82lyTjKKEnLX-Kob8NcYVNaDA,1095
102
- meshtrade-0.0.4.dist-info/METADATA,sha256=20ufo2BXf7mq1KIMItUifOKcLqCG1fVSPGCMNQOhgOs,6680
103
- meshtrade-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
104
- meshtrade-0.0.4.dist-info/top_level.txt,sha256=L1riO18qkORBnB4bc8vQrHyXdTkgl61nII3cLYQYD_g,10
105
- meshtrade-0.0.4.dist-info/RECORD,,
104
+ meshtrade-0.0.5.dist-info/licenses/LICENSE,sha256=7e68NmtCi6H_-e-fbQ82lyTjKKEnLX-Kob8NcYVNaDA,1095
105
+ meshtrade-0.0.5.dist-info/METADATA,sha256=5jp3xH1hM1R9-M6kH6yT11bnFsCeO7RzgSDnyLTPwoA,6681
106
+ meshtrade-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
107
+ meshtrade-0.0.5.dist-info/top_level.txt,sha256=L1riO18qkORBnB4bc8vQrHyXdTkgl61nII3cLYQYD_g,10
108
+ meshtrade-0.0.5.dist-info/RECORD,,