Skip to content

Commit 68f0eec

Browse files
authored
Merge branch 'main' into aliel-fix-cosmos
2 parents 0f0c7d1 + 7b86ff6 commit 68f0eec

16 files changed

+590
-234
lines changed

src/aleph/sdk/chains/ethereum.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,21 @@
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
2122
from ..evm_utils import (
2223
BALANCEOF_ABI,
2324
MIN_ETH_BALANCE,
2425
MIN_ETH_BALANCE_WEI,
26+
FlowUpdate,
27+
from_wei_token,
2528
get_chain_id,
2629
get_chains_with_super_token,
2730
get_rpc,
2831
get_super_token_address,
2932
get_token_address,
30-
to_human_readable_token,
3133
)
3234
from ..exceptions import BadSignatureError
3335
from ..utils import bytes_from_hex
@@ -106,8 +108,9 @@ def can_transact(self, block=True) -> bool:
106108
valid = balance > MIN_ETH_BALANCE_WEI if self.chain else False
107109
if not valid and block:
108110
raise InsufficientFundsError(
111+
token_type=TokenType.GAS,
109112
required_funds=MIN_ETH_BALANCE,
110-
available_funds=to_human_readable_token(balance),
113+
available_funds=float(from_wei_token(balance)),
111114
)
112115
return valid
113116

@@ -162,6 +165,12 @@ def get_super_token_balance(self) -> Decimal:
162165
return Decimal(contract.functions.balanceOf(self.get_address()).call())
163166
return Decimal(0)
164167

168+
def can_start_flow(self, flow: Decimal) -> bool:
169+
"""Check if the account has enough funds to start a Superfluid flow of the given size."""
170+
if not self.superfluid_connector:
171+
raise ValueError("Superfluid connector is required to check a flow")
172+
return self.superfluid_connector.can_start_flow(flow)
173+
165174
def create_flow(self, receiver: str, flow: Decimal) -> Awaitable[str]:
166175
"""Creat a Superfluid flow between this account and the receiver address."""
167176
if not self.superfluid_connector:
@@ -188,6 +197,19 @@ def delete_flow(self, receiver: str) -> Awaitable[str]:
188197
raise ValueError("Superfluid connector is required to delete a flow")
189198
return self.superfluid_connector.delete_flow(receiver=receiver)
190199

200+
def manage_flow(
201+
self,
202+
receiver: str,
203+
flow: Decimal,
204+
update_type: FlowUpdate,
205+
) -> Awaitable[Optional[str]]:
206+
"""Manage the Superfluid flow between this account and the receiver address."""
207+
if not self.superfluid_connector:
208+
raise ValueError("Superfluid connector is required to manage a flow")
209+
return self.superfluid_connector.manage_flow(
210+
receiver=receiver, flow=flow, update_type=update_type
211+
)
212+
191213

192214
def get_fallback_account(
193215
path: Optional[Path] = None, chain: Optional[Chain] = None

src/aleph/sdk/chains/evm.py

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from aleph_message.models import Chain
66
from eth_account import Account # type: ignore
77

8+
from ..evm_utils import FlowUpdate
89
from .common import get_fallback_private_key
910
from .ethereum import ETHAccount
1011

@@ -29,6 +30,9 @@ def get_token_balance(self) -> Decimal:
2930
def get_super_token_balance(self) -> Decimal:
3031
raise ValueError(f"Super token not implemented for this chain {self.CHAIN}")
3132

33+
def can_start_flow(self, flow: Decimal) -> bool:
34+
raise ValueError(f"Flow checking not implemented for this chain {self.CHAIN}")
35+
3236
def create_flow(self, receiver: str, flow: Decimal) -> Awaitable[str]:
3337
raise ValueError(f"Flow creation not implemented for this chain {self.CHAIN}")
3438

@@ -41,6 +45,11 @@ def update_flow(self, receiver: str, flow: Decimal) -> Awaitable[str]:
4145
def delete_flow(self, receiver: str) -> Awaitable[str]:
4246
raise ValueError(f"Flow deletion not implemented for this chain {self.CHAIN}")
4347

48+
def manage_flow(
49+
self, receiver: str, flow: Decimal, update_type: FlowUpdate
50+
) -> Awaitable[Optional[str]]:
51+
raise ValueError(f"Flow management not implemented for this chain {self.CHAIN}")
52+
4453

4554
def get_fallback_account(
4655
path: Optional[Path] = None, chain: Optional[Chain] = None

src/aleph/sdk/client/abstract.py

+48-34
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
from aleph_message.models import (
2222
AlephMessage,
23+
ExecutableContent,
2324
ItemHash,
2425
ItemType,
25-
MessagesResponse,
2626
MessageType,
2727
Payment,
2828
PostMessage,
@@ -41,7 +41,7 @@
4141
from aleph.sdk.utils import extended_json_encoder
4242

4343
from ..query.filters import MessageFilter, PostFilter
44-
from ..query.responses import PostsResponse, PriceResponse
44+
from ..query.responses import MessagesResponse, PostsResponse, PriceResponse
4545
from ..types import GenericMessage, StorageEnum
4646
from ..utils import Writable, compute_sha256
4747

@@ -110,7 +110,7 @@ async def get_posts_iterator(
110110
)
111111
page += 1
112112
for post in resp.posts:
113-
yield post
113+
yield post # type: ignore
114114

115115
@abstractmethod
116116
async def download_file(self, file_hash: str) -> bytes:
@@ -242,6 +242,18 @@ def watch_messages(
242242
"""
243243
raise NotImplementedError("Did you mean to import `AlephHttpClient`?")
244244

245+
@abstractmethod
246+
def get_estimated_price(
247+
self,
248+
content: ExecutableContent,
249+
) -> Coroutine[Any, Any, PriceResponse]:
250+
"""
251+
Get Instance/Program content estimated price
252+
253+
:param content: Instance or Program content
254+
"""
255+
raise NotImplementedError("Did you mean to import `AlephHttpClient`?")
256+
245257
@abstractmethod
246258
def get_program_price(
247259
self,
@@ -265,7 +277,7 @@ async def create_post(
265277
post_type: str,
266278
ref: Optional[str] = None,
267279
address: Optional[str] = None,
268-
channel: Optional[str] = None,
280+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
269281
inline: bool = True,
270282
storage_engine: StorageEnum = StorageEnum.storage,
271283
sync: bool = False,
@@ -290,9 +302,9 @@ async def create_post(
290302
async def create_aggregate(
291303
self,
292304
key: str,
293-
content: Mapping[str, Any],
305+
content: dict[str, Any],
294306
address: Optional[str] = None,
295-
channel: Optional[str] = None,
307+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
296308
inline: bool = True,
297309
sync: bool = False,
298310
) -> Tuple[AlephMessage, MessageStatus]:
@@ -302,7 +314,7 @@ async def create_aggregate(
302314
:param key: Key to use to store the content
303315
:param content: Content to store
304316
:param address: Address to use to sign the message
305-
:param channel: Channel to use (Default: "TEST")
317+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
306318
:param inline: Whether to write content inside the message (Default: True)
307319
:param sync: If true, waits for the message to be processed by the API server (Default: False)
308320
"""
@@ -321,7 +333,7 @@ async def create_store(
321333
ref: Optional[str] = None,
322334
storage_engine: StorageEnum = StorageEnum.storage,
323335
extra_fields: Optional[dict] = None,
324-
channel: Optional[str] = None,
336+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
325337
sync: bool = False,
326338
) -> Tuple[AlephMessage, MessageStatus]:
327339
"""
@@ -350,45 +362,47 @@ async def create_program(
350362
program_ref: str,
351363
entrypoint: str,
352364
runtime: str,
353-
environment_variables: Optional[Mapping[str, str]] = None,
354-
storage_engine: StorageEnum = StorageEnum.storage,
355-
channel: Optional[str] = None,
365+
metadata: Optional[dict[str, Any]] = None,
356366
address: Optional[str] = None,
357-
sync: bool = False,
358-
memory: Optional[int] = None,
367+
payment: Optional[Payment] = None,
359368
vcpus: Optional[int] = None,
369+
memory: Optional[int] = None,
360370
timeout_seconds: Optional[float] = None,
361-
persistent: bool = False,
362-
allow_amend: bool = False,
363371
internet: bool = True,
372+
allow_amend: bool = False,
364373
aleph_api: bool = True,
365374
encoding: Encoding = Encoding.zip,
375+
persistent: bool = False,
366376
volumes: Optional[List[Mapping]] = None,
367-
subscriptions: Optional[List[Mapping]] = None,
368-
metadata: Optional[Mapping[str, Any]] = None,
377+
environment_variables: Optional[dict[str, str]] = None,
378+
subscriptions: Optional[List[dict]] = None,
379+
sync: bool = False,
380+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
381+
storage_engine: StorageEnum = StorageEnum.storage,
369382
) -> Tuple[AlephMessage, MessageStatus]:
370383
"""
371384
Post a (create) PROGRAM message.
372385
373386
:param program_ref: Reference to the program to run
374387
:param entrypoint: Entrypoint to run
375388
:param runtime: Runtime to use
376-
:param environment_variables: Environment variables to pass to the program
377-
:param storage_engine: Storage engine to use (Default: "storage")
378-
:param channel: Channel to use (Default: "TEST")
389+
:param metadata: Metadata to attach to the message
379390
:param address: Address to use (Default: account.get_address())
380-
:param sync: If true, waits for the message to be processed by the API server
381-
:param memory: Memory in MB for the VM to be allocated (Default: 128)
391+
:param payment: Payment method used to pay for the program (Default: None)
382392
:param vcpus: Number of vCPUs to allocate (Default: 1)
393+
:param memory: Memory in MB for the VM to be allocated (Default: 128)
383394
:param timeout_seconds: Timeout in seconds (Default: 30.0)
384-
:param persistent: Whether the program should be persistent or not (Default: False)
385-
:param allow_amend: Whether the deployed VM image may be changed (Default: False)
386395
:param internet: Whether the VM should have internet connectivity. (Default: True)
396+
:param allow_amend: Whether the deployed VM image may be changed (Default: False)
387397
:param aleph_api: Whether the VM needs access to Aleph messages API (Default: True)
388398
:param encoding: Encoding to use (Default: Encoding.zip)
399+
:param persistent: Whether the program should be persistent or not (Default: False)
389400
:param volumes: Volumes to mount
401+
:param environment_variables: Environment variables to pass to the program
390402
:param subscriptions: Patterns of aleph.im messages to forward to the program's event receiver
391-
:param metadata: Metadata to attach to the message
403+
:param sync: If true, waits for the message to be processed by the API server
404+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
405+
:param storage_engine: Storage engine to use (Default: "storage")
392406
"""
393407
raise NotImplementedError(
394408
"Did you mean to import `AuthenticatedAlephHttpClient`?"
@@ -400,9 +414,9 @@ async def create_instance(
400414
rootfs: str,
401415
rootfs_size: int,
402416
payment: Optional[Payment] = None,
403-
environment_variables: Optional[Mapping[str, str]] = None,
417+
environment_variables: Optional[dict[str, str]] = None,
404418
storage_engine: StorageEnum = StorageEnum.storage,
405-
channel: Optional[str] = None,
419+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
406420
address: Optional[str] = None,
407421
sync: bool = False,
408422
memory: Optional[int] = None,
@@ -416,7 +430,7 @@ async def create_instance(
416430
volumes: Optional[List[Mapping]] = None,
417431
volume_persistence: str = "host",
418432
ssh_keys: Optional[List[str]] = None,
419-
metadata: Optional[Mapping[str, Any]] = None,
433+
metadata: Optional[dict[str, Any]] = None,
420434
requirements: Optional[HostRequirements] = None,
421435
) -> Tuple[AlephMessage, MessageStatus]:
422436
"""
@@ -427,7 +441,7 @@ async def create_instance(
427441
:param payment: Payment method used to pay for the instance
428442
:param environment_variables: Environment variables to pass to the program
429443
:param storage_engine: Storage engine to use (Default: "storage")
430-
:param channel: Channel to use (Default: "TEST")
444+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
431445
:param address: Address to use (Default: account.get_address())
432446
:param sync: If true, waits for the message to be processed by the API server
433447
:param memory: Memory in MB for the VM to be allocated (Default: 2048)
@@ -455,7 +469,7 @@ async def forget(
455469
hashes: List[ItemHash],
456470
reason: Optional[str],
457471
storage_engine: StorageEnum = StorageEnum.storage,
458-
channel: Optional[str] = None,
472+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
459473
address: Optional[str] = None,
460474
sync: bool = False,
461475
) -> Tuple[AlephMessage, MessageStatus]:
@@ -468,7 +482,7 @@ async def forget(
468482
:param hashes: Hashes of the messages to forget
469483
:param reason: Reason for forgetting the messages
470484
:param storage_engine: Storage engine to use (Default: "storage")
471-
:param channel: Channel to use (Default: "TEST")
485+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
472486
:param address: Address to use (Default: account.get_address())
473487
:param sync: If true, waits for the message to be processed by the API server (Default: False)
474488
"""
@@ -490,7 +504,7 @@ async def generate_signed_message(
490504
491505
:param message_type: Type of the message (PostMessage, ...)
492506
:param content: User-defined content of the message
493-
:param channel: Channel to use (Default: "TEST")
507+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
494508
:param allow_inlining: Whether to allow inlining the content of the message (Default: True)
495509
:param storage_engine: Storage engine to use (Default: "storage")
496510
"""
@@ -537,7 +551,7 @@ async def submit(
537551
self,
538552
content: Dict[str, Any],
539553
message_type: MessageType,
540-
channel: Optional[str] = None,
554+
channel: Optional[str] = settings.DEFAULT_CHANNEL,
541555
storage_engine: StorageEnum = StorageEnum.storage,
542556
allow_inlining: bool = True,
543557
sync: bool = False,
@@ -549,7 +563,7 @@ async def submit(
549563
550564
:param content: Content of the message
551565
:param message_type: Type of the message
552-
:param channel: Channel to use (Default: "TEST")
566+
:param channel: Channel to use (Default: "ALEPH-CLOUDSOLUTIONS")
553567
:param storage_engine: Storage engine to use (Default: "storage")
554568
:param allow_inlining: Whether to allow inlining the content of the message (Default: True)
555569
:param sync: If true, waits for the message to be processed by the API server (Default: False)

0 commit comments

Comments
 (0)