golem-vm-provider 0.1.52__py3-none-any.whl → 0.1.53__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: golem-vm-provider
3
- Version: 0.1.52
3
+ Version: 0.1.53
4
4
  Summary: VM on Golem Provider Node - Run your own provider node to offer VMs on the Golem Network
5
5
  Keywords: golem,vm,provider,cloud,decentralized
6
6
  Author: Phillip Jensen
@@ -454,6 +454,8 @@ poetry run golem-provider streams withdraw --vm-id <vm_id>
454
454
  poetry run golem-provider streams withdraw --all
455
455
  ```
456
456
 
457
+ Note: On testnets, the withdraw command auto-attempts to fund the provider's L2 address via the configured faucet if native gas balance is low.
458
+
457
459
  Configure monitor and withdraw via CLI:
458
460
 
459
461
  ```bash
@@ -13,13 +13,14 @@ provider/discovery/multi_advertiser.py,sha256=_J79wA1-XQ4GsLzt9KrKpWigGSGBqtut7D
13
13
  provider/discovery/resource_monitor.py,sha256=AmiEc7yBGEGXCunQ-QKmVgosDX3gOhK1Y58LJZXrwAs,949
14
14
  provider/discovery/resource_tracker.py,sha256=MP7IXd3aIMsjB4xz5Oj9zFDTEnvrnw-Cyxpl33xcJcc,6006
15
15
  provider/discovery/service.py,sha256=vX_mVSxvn3arnb2cKDM_SeJp1ZgPdImP2aUubeXgdRg,915
16
- provider/main.py,sha256=-dkQEwMrU2g1ljGrdf2B6P6CcgpDAjeCEqbBy_E4ybk,32799
16
+ provider/main.py,sha256=DJPVjvrTifFIw1l6jk0bwrOt35pmzmdVynv4A1fp9Y0,32137
17
17
  provider/network/port_verifier.py,sha256=3l6WNwBHydggJRFYkAsuBp1eCxaU619kjWuM-zSVj2o,13267
18
18
  provider/payments/blockchain_service.py,sha256=4GrzDKwCSUVoENqjD4RLyJ0qwBOJKMyVk5Li-XNsyTc,3567
19
19
  provider/payments/monitor.py,sha256=Rw17zYsxZre0zU6R0oeRNvVIzMdXLsgoUvSPHpJy6I0,4488
20
20
  provider/payments/stream_map.py,sha256=qk6Y8hS72DplAifZ0ZMWPHBAyc_3IWIQyWUBuCU3_To,1191
21
21
  provider/security/ethereum.py,sha256=EwPZj4JR8OEpto6LhKjuuT3Z9pBX6P7-UQaqJtqFkYQ,1242
22
22
  provider/security/faucet.py,sha256=8T4lW1fVQgUk8EQILgbrr9UUosw9e7eA40tlZ2_KCPQ,4368
23
+ provider/security/l2_faucet.py,sha256=qp6Q2F44jsX5w8zZ14gzILesiGSxJhC1E_VVgqerBgY,2388
23
24
  provider/service.py,sha256=IIjeSM9T4r616nBRnxCUum_sgbyRusMMcja3yQd8zQI,3383
24
25
  provider/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
26
  provider/utils/ascii_art.py,sha256=ykBFsztk57GIiz1NJ-EII5UvN74iECqQL4h9VmiW6Z8,3161
@@ -38,7 +39,7 @@ provider/vm/port_manager.py,sha256=iYSwjTjD_ziOhG8aI7juKHw1OwwRUTJQyQoRUNQvz9w,1
38
39
  provider/vm/provider.py,sha256=A7QN89EJjcSS40_SmKeinG1Jp_NGffJaLse-XdKciAs,1164
39
40
  provider/vm/proxy_manager.py,sha256=n4NTsyz2rtrvjtf_ceKBk-g2q_mzqPwruB1q7UlQVBc,14928
40
41
  provider/vm/service.py,sha256=Ki4SGNIZUq3XmaPMwAOoNzdZzKQsmFXid374wgjFPes,4636
41
- golem_vm_provider-0.1.52.dist-info/METADATA,sha256=-9IAEK4SfcsssCSwvniqN0hBaIvw3V8yxpEi9plknLw,17288
42
- golem_vm_provider-0.1.52.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
43
- golem_vm_provider-0.1.52.dist-info/entry_points.txt,sha256=5Jiie1dIXygmxmDW66bKKxQpmBLJ7leSKRrb8bkQALw,52
44
- golem_vm_provider-0.1.52.dist-info/RECORD,,
42
+ golem_vm_provider-0.1.53.dist-info/METADATA,sha256=mlrOME9VDQLPlCg8odOOc2u_q261s4Ox5C71-SjU8R0,17433
43
+ golem_vm_provider-0.1.53.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
44
+ golem_vm_provider-0.1.53.dist-info/entry_points.txt,sha256=5Jiie1dIXygmxmDW66bKKxQpmBLJ7leSKRrb8bkQALw,52
45
+ golem_vm_provider-0.1.53.dist-info/RECORD,,
provider/main.py CHANGED
@@ -147,38 +147,17 @@ def main():
147
147
  def wallet_faucet_l2():
148
148
  """Request L2 faucet funds for the provider's payment address (native ETH)."""
149
149
  from .config import settings
150
- from golem_faucet import PowFaucetClient
151
- from web3 import Web3
150
+ from .security.l2_faucet import L2FaucetService
152
151
  try:
153
152
  addr = settings.PROVIDER_ID
154
- faucet = PowFaucetClient(settings.L2_FAUCET_URL, settings.L2_CAPTCHA_URL, settings.L2_CAPTCHA_API_KEY)
155
- # Check current L2 balance
156
- w3 = Web3(Web3.HTTPProvider(settings.POLYGON_RPC_URL))
157
- bal = 0.0
158
- try:
159
- bal = float(w3.from_wei(w3.eth.get_balance(Web3.to_checksum_address(addr)), 'ether'))
160
- except Exception:
161
- pass
162
- if bal > 0.01:
163
- print(f"Sufficient L2 funds ({bal} ETH); skipping faucet.")
164
- return
165
153
  async def _run():
166
- chall = await faucet.get_challenge()
167
- if not chall:
168
- print("Failed to get challenge")
169
- raise typer.Exit(code=1)
170
- sols = []
171
- for salt, target in chall.get('challenge') or []:
172
- sols.append((salt, target, PowFaucetClient.solve_challenge(salt, target)))
173
- redeemed = await faucet.redeem(chall.get('token'), sols)
174
- if not redeemed:
175
- print("Failed to redeem solutions")
176
- raise typer.Exit(code=1)
177
- tx = await faucet.request_funds(addr, redeemed)
154
+ svc = L2FaucetService(settings)
155
+ tx = await svc.request_funds(addr)
178
156
  if tx:
179
157
  print(f"Faucet tx: {tx}")
180
158
  else:
181
- print("Faucet request failed")
159
+ # Either skipped due to sufficient balance or failed
160
+ pass
182
161
  asyncio.run(_run())
183
162
  except Exception as e:
184
163
  print(f"Error: {e}")
@@ -497,6 +476,7 @@ def streams_withdraw(
497
476
  """Withdraw vested funds for one or all streams."""
498
477
  from .container import Container
499
478
  from .config import settings
479
+ from .security.l2_faucet import L2FaucetService
500
480
  try:
501
481
  if not vm_id and not all_streams:
502
482
  print("Specify --vm-id or --all")
@@ -505,6 +485,12 @@ def streams_withdraw(
505
485
  c.config.from_pydantic(settings)
506
486
  stream_map = c.stream_map()
507
487
  client = c.stream_client()
488
+ # Ensure we have L2 gas for withdrawals (testnets)
489
+ try:
490
+ asyncio.run(L2FaucetService(settings).request_funds(settings.PROVIDER_ID))
491
+ except Exception:
492
+ # Non-fatal; proceed with withdraw attempt
493
+ pass
508
494
  targets = []
509
495
  if all_streams:
510
496
  items = asyncio.run(stream_map.all_items())
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional, List, Tuple
4
+
5
+ from web3 import Web3
6
+ from golem_faucet import PowFaucetClient
7
+ from ..utils.logging import setup_logger
8
+
9
+ logger = setup_logger(__name__)
10
+
11
+
12
+ class L2FaucetService:
13
+ """Request native ETH on the L2 payments chain via PoW faucet.
14
+
15
+ Uses provider settings for RPC and faucet endpoints.
16
+ """
17
+
18
+ def __init__(self, config):
19
+ # Config is expected to expose POLYGON_RPC_URL, L2_* faucet fields
20
+ self.cfg = config
21
+ self.web3 = Web3(Web3.HTTPProvider(config.POLYGON_RPC_URL))
22
+ self.client = PowFaucetClient(
23
+ faucet_url=getattr(config, "L2_FAUCET_URL", "https://l2.holesky.golemdb.io/faucet"),
24
+ captcha_base_url=getattr(config, "L2_CAPTCHA_URL", "https://cap.gobas.me"),
25
+ captcha_api_key=getattr(config, "L2_CAPTCHA_API_KEY", "05381a2cef5e"),
26
+ )
27
+
28
+ def _balance_eth(self, address: str) -> float:
29
+ try:
30
+ wei = self.web3.eth.get_balance(Web3.to_checksum_address(address))
31
+ return float(self.web3.from_wei(wei, "ether"))
32
+ except Exception as e:
33
+ logger.warning(f"L2 balance check failed: {e}")
34
+ return 0.0
35
+
36
+ async def request_funds(self, address: str) -> Optional[str]:
37
+ """Ensure some native ETH on L2; if low, solve PoW and request faucet payout.
38
+
39
+ Returns tx hash string on payout, or None if skipped/failed.
40
+ """
41
+ bal = self._balance_eth(address)
42
+ if bal > 0.01:
43
+ logger.info(f"Sufficient L2 funds ({bal} ETH), skipping faucet.")
44
+ return None
45
+ chall = await self.client.get_challenge()
46
+ if not chall:
47
+ logger.error("could not fetch faucet challenge")
48
+ return None
49
+ token = chall.get("token")
50
+ challenge_list = chall.get("challenge") or []
51
+ solutions: List[Tuple[str, str, int]] = []
52
+ for salt, target in challenge_list:
53
+ nonce = PowFaucetClient.solve_challenge(salt, target)
54
+ solutions.append((salt, target, nonce))
55
+ redeemed = await self.client.redeem(token, solutions)
56
+ if not redeemed:
57
+ logger.error("failed to redeem challenge")
58
+ return None
59
+ tx = await self.client.request_funds(address, redeemed)
60
+ if tx:
61
+ logger.success(f"L2 faucet sent tx: {tx}")
62
+ return tx
63
+