|
11 | 11 | Run this example: uv run python -m arkiv_starter.01_clients |
12 | 12 | """ |
13 | 13 |
|
14 | | -from typing import cast |
| 14 | +import socket |
| 15 | +from typing import Optional, cast |
15 | 16 | from web3.providers.base import BaseProvider |
16 | 17 | from arkiv import Arkiv, NamedAccount |
17 | 18 | from arkiv.provider import ProviderBuilder |
18 | | - |
| 19 | +from urllib.parse import urlparse |
| 20 | + |
| 21 | +EXTERNAL_RPC_URL: str = "https://mendoza.hoodi.arkiv.network/rpc" |
| 22 | + |
| 23 | +def is_rpc_reachable(rpc_url: str, timeout: float = 2.0) -> bool: |
| 24 | + """Check if RPC endpoint is reachable using a simple socket connection.""" |
| 25 | + try: |
| 26 | + parsed = urlparse(rpc_url) |
| 27 | + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 28 | + sock.settimeout(timeout) |
| 29 | + host = parsed.hostname or "127.0.0.1" |
| 30 | + port = parsed.port or (443 if parsed.scheme == "https" else 8545) |
| 31 | + result = sock.connect_ex((host, port)) |
| 32 | + sock.close() |
| 33 | + return result == 0 |
| 34 | + except Exception: |
| 35 | + return False |
19 | 36 |
|
20 | 37 | print("=" * 70) |
21 | 38 | print("PATTERN 1: Default Constructor (Simplest)") |
|
46 | 63 | print("=" * 70) |
47 | 64 | print("\n🚀 Creating client with custom provider...") |
48 | 65 | print(" - Connect to specific RPC URL") |
49 | | -print(" - Useful for remote nodes or specific configurations\n") |
| 66 | +print(" - Useful for remote nodes or specific configurations") |
| 67 | +print(" - Fallback to local node if external node not reachable\n") |
50 | 68 |
|
51 | | -# Use the node from the default client |
52 | 69 | local_node = client.node |
53 | | -assert local_node is not None, "Default client should have started a node" |
54 | | -rpc_url = local_node.http_url |
| 70 | +if is_rpc_reachable(EXTERNAL_RPC_URL): |
| 71 | + print(f"🌐 External RPC URL is reachable: {EXTERNAL_RPC_URL}\n") |
| 72 | + rpc_url = EXTERNAL_RPC_URL |
| 73 | +else: |
| 74 | + print(f"⚠️ External RPC URL is NOT reachable: {EXTERNAL_RPC_URL}") |
| 75 | + assert local_node is not None, "Default client should have started a node" |
| 76 | + rpc_url = local_node.http_url |
| 77 | + print(f" Falling back to local node RPC URL: {rpc_url}\n") |
55 | 78 |
|
56 | 79 | provider = cast(BaseProvider, ProviderBuilder().custom(url=rpc_url).build()) |
57 | 80 | # Note: When only providing provider, client doesn't auto-create account |
|
62 | 85 | print(f" Provider: {provider}") |
63 | 86 | print(f" Note: No default account - you must provide one for transactions\n") |
64 | 87 |
|
65 | | - |
66 | 88 | print("=" * 70) |
67 | 89 | print("PATTERN 3: Custom Account (Specific Private Key)") |
68 | 90 | print("=" * 70) |
|
71 | 93 | print(" - Useful for production with specific keys\n") |
72 | 94 |
|
73 | 95 | account = NamedAccount.create("custom-account") |
74 | | -local_node.fund_account(account) # Fund the new account |
| 96 | +if local_node: |
| 97 | + local_node.fund_account(account) # Fund the new account |
75 | 98 |
|
76 | 99 | custom_account_client = Arkiv(provider, account=account) |
| 100 | +custom_account_balance = custom_account_client.eth.get_balance(account.address) |
77 | 101 |
|
78 | 102 | print(f"✅ Client with custom account created!") |
79 | 103 | print(f" Account: {account.address}") |
80 | 104 | print(f" Account name: {account.name}") |
81 | | -print(f" Balance: {custom_account_client.eth.get_balance(account.address)/10**18} ETH\n") |
| 105 | +print(f" Balance: {custom_account_balance/10**18} ETH\n") |
82 | 106 |
|
83 | 107 | # Quick test |
84 | | -entity_key2, receipt2 = custom_account_client.arkiv.create_entity( |
85 | | - payload=b"Test from custom account", |
86 | | - content_type="text/plain", |
87 | | - expires_in=3600 |
88 | | -) |
89 | | -print(f"✅ Test entity created: {entity_key2}\n") |
| 108 | +if custom_account_balance > 0: |
| 109 | + print("💸 Creating test entity with custom account...") |
| 110 | + entity_key2, receipt2 = custom_account_client.arkiv.create_entity( |
| 111 | + payload=b"Test from custom account", |
| 112 | + content_type="text/plain", |
| 113 | + expires_in=3600 |
| 114 | + ) |
| 115 | + print(f"✅ Test entity created: {entity_key2}\n") |
90 | 116 |
|
91 | 117 |
|
92 | 118 | print("=" * 70) |
|
0 commit comments