hippius 0.1.6__py3-none-any.whl → 0.1.7__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.
hippius_sdk/substrate.py CHANGED
@@ -9,6 +9,13 @@ import json
9
9
  from typing import Dict, Any, Optional, List, Union
10
10
  from substrateinterface import SubstrateInterface, Keypair
11
11
  from dotenv import load_dotenv
12
+ from hippius_sdk.config import (
13
+ get_config_value,
14
+ get_seed_phrase,
15
+ set_seed_phrase,
16
+ get_account_address,
17
+ get_active_account,
18
+ )
12
19
 
13
20
  # Load environment variables
14
21
  load_dotenv()
@@ -37,32 +44,51 @@ class SubstrateClient:
37
44
  """
38
45
  Client for interacting with the Hippius Substrate blockchain.
39
46
 
47
+ Provides functionality for storage requests and other blockchain operations.
40
48
  Note: This functionality is not fully implemented yet and is under active development.
41
49
  """
42
50
 
43
- def __init__(self, url: str = None, seed_phrase: Optional[str] = None):
51
+ def __init__(
52
+ self,
53
+ url: Optional[str] = None,
54
+ seed_phrase: Optional[str] = None,
55
+ password: Optional[str] = None,
56
+ account_name: Optional[str] = None,
57
+ ):
44
58
  """
45
59
  Initialize the Substrate client.
46
60
 
47
61
  Args:
48
- url: WebSocket URL of the Hippius substrate node
49
- If not provided, uses SUBSTRATE_URL from environment
50
- seed_phrase: Seed phrase for the account (mnemonic)
51
- If not provided, uses SUBSTRATE_SEED_PHRASE from environment
62
+ url: WebSocket URL of the Hippius substrate node (from config if None)
63
+ seed_phrase: Seed phrase for the account (mnemonic) (from config if None)
64
+ password: Optional password to decrypt the seed phrase if it's encrypted
65
+ account_name: Optional name of the account to use (uses active account if None)
52
66
  """
53
- if not url:
54
- url = os.getenv("SUBSTRATE_URL", "wss://rpc.hippius.network")
67
+ # Load configuration values if not explicitly provided
68
+ if url is None:
69
+ url = get_config_value("substrate", "url", "wss://rpc.hippius.network")
55
70
 
56
71
  # Store URL and initialize variables
57
72
  self.url = url
58
73
  self._substrate = None
59
74
  self._keypair = None
75
+ self._account_name = account_name or get_active_account()
76
+ self._account_address = None
77
+ self._read_only = False
78
+
79
+ # Get the account address for read-only operations
80
+ addr = get_account_address(self._account_name)
81
+ if addr:
82
+ self._account_address = addr
60
83
 
61
- # Set seed phrase if provided or available in environment
84
+ # Set seed phrase if provided or available in configuration
62
85
  if seed_phrase:
63
86
  self.set_seed_phrase(seed_phrase)
64
- elif os.getenv("SUBSTRATE_SEED_PHRASE"):
65
- self.set_seed_phrase(os.getenv("SUBSTRATE_SEED_PHRASE"))
87
+ else:
88
+ # Only try to get the seed phrase if we need it for the current operation
89
+ # We'll defer this to when it's actually needed
90
+ self._seed_phrase = None
91
+ self._seed_phrase_password = password
66
92
 
67
93
  # Don't connect immediately to avoid exceptions during initialization
68
94
  # Connection will happen lazily when needed
@@ -84,11 +110,19 @@ class SubstrateClient:
84
110
  # Only create keypair if seed phrase is available
85
111
  if hasattr(self, "_seed_phrase") and self._seed_phrase:
86
112
  self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
113
+ self._account_address = self._keypair.ss58_address
87
114
  print(
88
115
  f"Connected successfully. Account address: {self._keypair.ss58_address}"
89
116
  )
117
+ self._read_only = False
118
+ elif self._account_address:
119
+ print(
120
+ f"Connected successfully in read-only mode. Account address: {self._account_address}"
121
+ )
122
+ self._read_only = True
90
123
  else:
91
- print("Connected successfully (read-only mode, no keypair)")
124
+ print("Connected successfully (read-only mode, no account)")
125
+ self._read_only = True
92
126
 
93
127
  return True
94
128
 
@@ -100,6 +134,48 @@ class SubstrateClient:
100
134
 
101
135
  return False
102
136
 
137
+ def _ensure_keypair(self) -> bool:
138
+ """
139
+ Ensure we have a keypair for signing transactions.
140
+ Will prompt for password if needed.
141
+
142
+ Returns:
143
+ bool: True if keypair is available, False if it couldn't be created
144
+ """
145
+ if self._keypair:
146
+ return True
147
+
148
+ # If we have a seed phrase, create the keypair
149
+ if hasattr(self, "_seed_phrase") and self._seed_phrase:
150
+ try:
151
+ self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
152
+ self._account_address = self._keypair.ss58_address
153
+ print(f"Keypair created for account: {self._keypair.ss58_address}")
154
+ self._read_only = False
155
+ return True
156
+ except Exception as e:
157
+ print(f"Warning: Could not create keypair from seed phrase: {e}")
158
+ return False
159
+
160
+ # Otherwise, try to get the seed phrase from config
161
+ try:
162
+ config_seed = get_seed_phrase(
163
+ self._seed_phrase_password, self._account_name
164
+ )
165
+ if config_seed:
166
+ self._seed_phrase = config_seed
167
+ self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
168
+ self._account_address = self._keypair.ss58_address
169
+ print(f"Keypair created for account: {self._keypair.ss58_address}")
170
+ self._read_only = False
171
+ return True
172
+ else:
173
+ print("No seed phrase available. Cannot sign transactions.")
174
+ return False
175
+ except Exception as e:
176
+ print(f"Warning: Could not get seed phrase from config: {e}")
177
+ return False
178
+
103
179
  def set_seed_phrase(self, seed_phrase: str) -> None:
104
180
  """
105
181
  Set or update the seed phrase used for signing transactions.
@@ -110,17 +186,15 @@ class SubstrateClient:
110
186
  if not seed_phrase or not seed_phrase.strip():
111
187
  raise ValueError("Seed phrase cannot be empty")
112
188
 
113
- # Store the seed phrase
189
+ # Store the seed phrase in memory for this session
114
190
  self._seed_phrase = seed_phrase.strip()
191
+ self._read_only = False
115
192
 
116
193
  # Try to create the keypair if possible
117
194
  try:
118
- if hasattr(self, "_substrate") and self._substrate:
119
- # If we already have a connection, create the keypair
120
- self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
121
- print(f"Keypair created for account: {self._keypair.ss58_address}")
122
- else:
123
- print(f"Seed phrase set (keypair will be created when connecting)")
195
+ self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
196
+ self._account_address = self._keypair.ss58_address
197
+ print(f"Keypair created for account: {self._keypair.ss58_address}")
124
198
  except Exception as e:
125
199
  print(f"Warning: Could not create keypair from seed phrase: {e}")
126
200
  print(f"Keypair will be created when needed")
@@ -147,6 +221,10 @@ class SubstrateClient:
147
221
  ... FileInput("QmHash2", "file2.jpg")
148
222
  ... ])
149
223
  """
224
+ # Check if we have a keypair for signing transactions
225
+ if not self._ensure_keypair():
226
+ raise ValueError("Seed phrase must be set before making transactions")
227
+
150
228
  # Convert any dict inputs to FileInput objects
151
229
  file_inputs = []
152
230
  for file in files:
@@ -183,20 +261,6 @@ class SubstrateClient:
183
261
  )
184
262
  print(f"Connected to Substrate node at {self.url}")
185
263
 
186
- # Create keypair from seed phrase if not already created
187
- if not hasattr(self, "_keypair") or self._keypair is None:
188
- if not hasattr(self, "_seed_phrase") or not self._seed_phrase:
189
- raise ValueError(
190
- "Seed phrase must be set before making transactions"
191
- )
192
-
193
- print("Creating keypair from seed phrase...")
194
- self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
195
- print(f"Keypair created for address: {self._keypair.ss58_address}")
196
-
197
- # Prepare storage request call
198
- print("Preparing marketplace.storageRequest batch call...")
199
-
200
264
  # Format files for the batch call - all files are included in a single array
201
265
  formatted_files = []
202
266
  for file_input in file_inputs:
@@ -315,6 +379,10 @@ class SubstrateClient:
315
379
  Returns:
316
380
  str: Transaction hash
317
381
  """
382
+ # This requires a keypair for signing
383
+ if not self._ensure_keypair():
384
+ raise ValueError("Seed phrase must be set before making transactions")
385
+
318
386
  raise NotImplementedError("Substrate functionality is not implemented yet.")
319
387
 
320
388
  def get_storage_fee(self, file_size_mb: float) -> float:
@@ -369,19 +437,17 @@ class SubstrateClient:
369
437
  )
370
438
  print(f"Connected to Substrate node at {self.url}")
371
439
 
372
- # Use provided account address or default to keypair address
440
+ # Use provided account address or default to keypair/configured address
373
441
  if not account_address:
374
- if not hasattr(self, "_keypair") or self._keypair is None:
375
- if not hasattr(self, "_seed_phrase") or not self._seed_phrase:
376
- raise ValueError(
377
- "No account address provided and no seed phrase is set"
378
- )
379
-
380
- print("Creating keypair from seed phrase to get account address...")
381
- self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
382
-
383
- account_address = self._keypair.ss58_address
384
- print(f"Using keypair address: {account_address}")
442
+ if self._account_address:
443
+ account_address = self._account_address
444
+ print(f"Using account address: {account_address}")
445
+ else:
446
+ # Try to get the address from the keypair (requires seed phrase)
447
+ if not self._ensure_keypair():
448
+ raise ValueError("No account address available")
449
+ account_address = self._keypair.ss58_address
450
+ print(f"Using keypair address: {account_address}")
385
451
 
386
452
  # Query the blockchain for free credits
387
453
  print(f"Querying free credits for account: {account_address}")
@@ -435,19 +501,17 @@ class SubstrateClient:
435
501
  )
436
502
  print(f"Connected to Substrate node at {self.url}")
437
503
 
438
- # Use provided account address or default to keypair address
504
+ # Use provided account address or default to keypair/configured address
439
505
  if not account_address:
440
- if not hasattr(self, "_keypair") or self._keypair is None:
441
- if not hasattr(self, "_seed_phrase") or not self._seed_phrase:
442
- raise ValueError(
443
- "No account address provided and no seed phrase is set"
444
- )
445
-
446
- print("Creating keypair from seed phrase to get account address...")
447
- self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
448
-
449
- account_address = self._keypair.ss58_address
450
- print(f"Using keypair address: {account_address}")
506
+ if self._account_address:
507
+ account_address = self._account_address
508
+ print(f"Using account address: {account_address}")
509
+ else:
510
+ # Try to get the address from the keypair (requires seed phrase)
511
+ if not self._ensure_keypair():
512
+ raise ValueError("No account address available")
513
+ account_address = self._keypair.ss58_address
514
+ print(f"Using keypair address: {account_address}")
451
515
 
452
516
  # Query the blockchain for user file hashes
453
517
  print(f"Querying file hashes for account: {account_address}")
@@ -516,19 +580,17 @@ class SubstrateClient:
516
580
  )
517
581
  print(f"Connected to Substrate node at {self.url}")
518
582
 
519
- # Use provided account address or default to keypair address
583
+ # Use provided account address or default to keypair/configured address
520
584
  if not account_address:
521
- if not hasattr(self, "_keypair") or self._keypair is None:
522
- if not hasattr(self, "_seed_phrase") or not self._seed_phrase:
523
- raise ValueError(
524
- "No account address provided and no seed phrase is set"
525
- )
526
-
527
- print("Creating keypair from seed phrase to get account address...")
528
- self._keypair = Keypair.create_from_mnemonic(self._seed_phrase)
529
-
530
- account_address = self._keypair.ss58_address
531
- print(f"Using keypair address: {account_address}")
585
+ if self._account_address:
586
+ account_address = self._account_address
587
+ print(f"Using account address: {account_address}")
588
+ else:
589
+ # Try to get the address from the keypair (requires seed phrase)
590
+ if not self._ensure_keypair():
591
+ raise ValueError("No account address available")
592
+ account_address = self._keypair.ss58_address
593
+ print(f"Using keypair address: {account_address}")
532
594
 
533
595
  # Prepare the JSON-RPC request
534
596
  request = {
@@ -1,9 +0,0 @@
1
- hippius_sdk/__init__.py,sha256=SwOREu9EJZ9ZRM-rSPX0o1hhsOUIADuP3CxoF4Mp_qI,288
2
- hippius_sdk/cli.py,sha256=WfjU9nuUBXN6Tu25PnOpLHftClP_umh6Zl9t4BOzAfo,30576
3
- hippius_sdk/client.py,sha256=bHsoadw2WMMZDU7D0r02nHeU82PAa4cvmblieDzBw54,13305
4
- hippius_sdk/ipfs.py,sha256=C9oMTBefCIfWFUsUBxhUkivz5rIUkhHKJtqdVIkMAbc,61475
5
- hippius_sdk/substrate.py,sha256=mfDxbKn9HdtcK1xEnj_BnnreRw8ITZswtDoBhtliidM,27278
6
- hippius-0.1.6.dist-info/METADATA,sha256=295Uv9mZq1G0pypT4PibEmTDVNRr7gM_ScFNVPZTfdo,16580
7
- hippius-0.1.6.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
8
- hippius-0.1.6.dist-info/entry_points.txt,sha256=b1lo60zRXmv1ud-c5BC-cJcAfGE5FD4qM_nia6XeQtM,98
9
- hippius-0.1.6.dist-info/RECORD,,