Skip to content

Commit 30190e6

Browse files
committed
Add token_type to InsufficientFundsError + displayable_amount()
1 parent 84e6a80 commit 30190e6

File tree

7 files changed

+53
-17
lines changed

7 files changed

+53
-17
lines changed

src/aleph/sdk/chains/ethereum.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from web3.types import TxParams, TxReceipt
1616

1717
from aleph.sdk.exceptions import InsufficientFundsError
18+
from aleph.sdk.types import TokenType
1819

1920
from ..conf import settings
2021
from ..connectors.superfluid import Superfluid
@@ -107,6 +108,7 @@ def can_transact(self, block=True) -> bool:
107108
valid = balance > MIN_ETH_BALANCE_WEI if self.chain else False
108109
if not valid and block:
109110
raise InsufficientFundsError(
111+
token_type=TokenType.GAS,
110112
required_funds=MIN_ETH_BALANCE,
111113
available_funds=float(from_wei_token(balance)),
112114
)

src/aleph/sdk/client/authenticated_http.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
from ..conf import settings
4040
from ..exceptions import BroadcastError, InsufficientFundsError, InvalidMessageError
41-
from ..types import Account, StorageEnum
41+
from ..types import Account, StorageEnum, TokenType
4242
from ..utils import extended_json_encoder, make_instance_content, parse_volume
4343
from .abstract import AuthenticatedAlephClient
4444
from .http import AlephHttpClient
@@ -569,7 +569,9 @@ async def create_instance(
569569
account_balance = float(error["account_balance"])
570570
required_balance = float(error["required_balance"])
571571
raise InsufficientFundsError(
572-
required_funds=required_balance, available_funds=account_balance
572+
token_type=TokenType.ALEPH,
573+
required_funds=required_balance,
574+
available_funds=account_balance,
573575
)
574576
else:
575577
raise ValueError(f"Unknown error code {error_code}: {rejected_message}")

src/aleph/sdk/connectors/superfluid.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
from eth_utils import to_normalized_address
77
from superfluid import CFA_V1, Operation, Web3FlowInfo
88

9-
from aleph.sdk.exceptions import InsufficientFundsError
10-
11-
from ..evm_utils import (
9+
from aleph.sdk.evm_utils import (
1210
FlowUpdate,
1311
from_wei_token,
1412
get_super_token_address,
1513
to_wei_token,
1614
)
15+
from aleph.sdk.exceptions import InsufficientFundsError
16+
from aleph.sdk.types import TokenType
1717

1818
if TYPE_CHECKING:
1919
from aleph.sdk.chains.ethereum import ETHAccount
@@ -57,6 +57,7 @@ def can_start_flow(self, flow: Decimal, block=True) -> bool:
5757
valid = balance > MIN_FLOW_4H
5858
if not valid and block:
5959
raise InsufficientFundsError(
60+
token_type=TokenType.ALEPH,
6061
required_funds=float(MIN_FLOW_4H),
6162
available_funds=float(from_wei_token(balance)),
6263
)

src/aleph/sdk/evm_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def to_wei_token(amount: Decimal) -> Decimal:
3939

4040
def ether_rounding(amount: Decimal) -> Decimal:
4141
"""Rounds the given value to 18 decimals."""
42-
return amount.quantize(Decimal(1) / 10**18, rounding=ROUND_CEILING)
42+
return amount.quantize(Decimal(1) / Decimal(10**18), rounding=ROUND_CEILING)
4343

4444

4545
def get_chain_id(chain: Union[Chain, str, None]) -> Optional[int]:

src/aleph/sdk/exceptions.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from abc import ABC
22

3+
from .types import TokenType
4+
from .utils import displayable_amount
5+
36

47
class QueryError(ABC, ValueError):
58
"""The result of an API query is inconsistent."""
@@ -69,14 +72,18 @@ class ForgottenMessageError(QueryError):
6972
class InsufficientFundsError(Exception):
7073
"""Raised when the account does not have enough funds to perform an action"""
7174

75+
token_type: TokenType
7276
required_funds: float
7377
available_funds: float
7478

75-
def __init__(self, required_funds: float, available_funds: float):
76-
self.required_funds = required_funds
77-
self.available_funds = available_funds
79+
def __init__(
80+
self, token_type: TokenType, required_funds: float, available_funds: float
81+
):
82+
self.token_type = token_type
83+
self.required_funds = displayable_amount(required_funds, decimals=8)
84+
self.available_funds = displayable_amount(available_funds, decimals=8)
7885
super().__init__(
79-
f"Insufficient funds: required {required_funds}, available {available_funds}"
86+
f"Insufficient funds ({self.token_type.value}): required {self.required_funds}, available {self.available_funds}"
8087
)
8188

8289

src/aleph/sdk/types.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,20 @@ class ChainInfo(BaseModel):
8383

8484

8585
class StoredContent(BaseModel):
86+
"""
87+
A stored content.
88+
"""
89+
8690
filename: Optional[str]
8791
hash: Optional[str]
8892
url: Optional[str]
8993
error: Optional[str]
94+
95+
96+
class TokenType(str, Enum):
97+
"""
98+
A token type.
99+
"""
100+
101+
GAS = "GAS"
102+
ALEPH = "ALEPH"

src/aleph/sdk/utils.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import subprocess
1010
from datetime import date, datetime, time
11+
from decimal import ROUND_CEILING, Decimal
1112
from enum import Enum
1213
from pathlib import Path
1314
from shutil import make_archive
@@ -28,13 +29,7 @@
2829
from uuid import UUID
2930
from zipfile import BadZipFile, ZipFile
3031

31-
from aleph_message.models import (
32-
Chain,
33-
InstanceContent,
34-
ItemHash,
35-
MessageType,
36-
ProgramContent,
37-
)
32+
from aleph_message.models import Chain, InstanceContent, ItemHash, MessageType
3833
from aleph_message.models.execution.base import Payment, PaymentType
3934
from aleph_message.models.execution.environment import (
4035
HostRequirements,
@@ -418,6 +413,22 @@ def safe_getattr(obj, attr, default=None):
418413
return obj
419414

420415

416+
def displayable_amount(
417+
amount: str | int | float | Decimal, decimals: Optional[int] = None
418+
) -> str:
419+
"""Returns the amount as a string without unnecessary decimals."""
420+
421+
str_amount = ""
422+
try:
423+
dec_amount = Decimal(amount)
424+
if decimals:
425+
dec_amount = dec_amount.quantize(Decimal(1) / Decimal(10**decimals))
426+
str_amount = str(format(dec_amount.normalize(), "f"))
427+
except ValueError as e:
428+
raise ValueError(f"Invalid amount: {amount}") from e
429+
return str_amount
430+
431+
421432
def make_instance_content(
422433
rootfs: str,
423434
rootfs_size: int,

0 commit comments

Comments
 (0)