hippius 0.2.21__py3-none-any.whl → 0.2.23__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.1
2
2
  Name: hippius
3
- Version: 0.2.21
3
+ Version: 0.2.23
4
4
  Summary: Python SDK and CLI for Hippius blockchain storage
5
5
  Home-page: https://github.com/thenervelab/hippius-sdk
6
6
  Author: Dubs
@@ -1,10 +1,10 @@
1
- hippius_sdk/__init__.py,sha256=GR_6lzziCmPq3cvSasIrT3n2Px3l6Jv1OXAEXDZ0fX0,1474
1
+ hippius_sdk/__init__.py,sha256=6ONUk4AypnusMGzUTnYRedLDq_bL-T6Fiyx5eXz0w78,1474
2
2
  hippius_sdk/cli.py,sha256=aqKOYSBSWt7UhcpFt7wf9yIPJ3bznpsJ6ehOnuZ4usI,18235
3
3
  hippius_sdk/cli_assets.py,sha256=V3MX63QTiex6mCp0VDXQJ7cagm5v1s4xtsu8c1O4G_k,371
4
4
  hippius_sdk/cli_handlers.py,sha256=TQNE9os87gRzRKLEO-SIwhFnBtEFMiaSESv-Bu7omfo,128909
5
5
  hippius_sdk/cli_parser.py,sha256=z7UvgWvvy04ey-R56qZiCqYc_9RaNq1rVDkQyXoK3JU,21100
6
6
  hippius_sdk/cli_rich.py,sha256=_jTBYMdHi2--fIVwoeNi-EtkdOb6Zy_O2TUiGvU3O7s,7324
7
- hippius_sdk/client.py,sha256=ktlv-s7H53h4zWcdz1EYf6fAqioohcFAxhRDKtljlEg,22252
7
+ hippius_sdk/client.py,sha256=Hj87gu5kapNM0V0-EgwJBsuA63HTsVHFGr2VnmwFH6I,22298
8
8
  hippius_sdk/config.py,sha256=Hf_aUYzG9ylzqauA_ABUSSB5mBTYbp-VtB36VQt2XDw,21981
9
9
  hippius_sdk/db/README.md,sha256=okDeI1qgkaZqXSlJ8L0xIE4UpuxO-qEGPIbXUvSHQjU,2030
10
10
  hippius_sdk/db/env.db.template,sha256=_6hEC3IvkzCDOAzG1_yJUKRUfCTMciNaJUicZpMCat4,217
@@ -12,12 +12,12 @@ hippius_sdk/db/migrations/20241201000001_create_key_storage_tables.sql,sha256=mi
12
12
  hippius_sdk/db/setup_database.sh,sha256=bDeIiTnMuX0AYCdefAfEI1CyXho6A6kLzufsDZFSXpE,3118
13
13
  hippius_sdk/db_utils.py,sha256=-x0rbN0as7Tn3PJPZBYCgreZe52FLH40ppA1TLxsg90,1851
14
14
  hippius_sdk/errors.py,sha256=LScJJmawVAx7aRzqqQguYSkf9iazSjEQEBNlD_GXZ6Y,1589
15
- hippius_sdk/ipfs.py,sha256=QjqBYnhqzAiST3CNCCLxwPxEMGaV2iLwk_IBTp740wg,93188
15
+ hippius_sdk/ipfs.py,sha256=D4QYDTRZEJVF0OVdNYGn6MvWmb1A9Rm8MFBKZk9-GVs,94419
16
16
  hippius_sdk/ipfs_core.py,sha256=eOOgLoyP9mvwndnCjldnTc7z94ImYCXY3nm7JU3e_Mo,12676
17
17
  hippius_sdk/key_storage.py,sha256=oxfRRQXu8XVncUjhKJJ8rsc81JAkaj9MqZEwQa96idc,9474
18
- hippius_sdk/substrate.py,sha256=AqfQNl5Qv_s6roOESSdwleX0-VGyu5sh3m5-dYZp5ek,49079
18
+ hippius_sdk/substrate.py,sha256=-lIavQkfE6Kw2KzllH9IMgNkzl2d6vEmU3RmwKNJQvc,48093
19
19
  hippius_sdk/utils.py,sha256=rJ611yvwKSyiBpYU3w-SuyQxoghMGU-ePuslrPv5H5g,7388
20
- hippius-0.2.21.dist-info/METADATA,sha256=iBEURRYrrokbmCufUVrac5PlnWErQ72on4cycxevlqU,30088
21
- hippius-0.2.21.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
22
- hippius-0.2.21.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
23
- hippius-0.2.21.dist-info/RECORD,,
20
+ hippius-0.2.23.dist-info/METADATA,sha256=i5wAnryTHWL_nEq-LGR8KrFdvuVefhqwCVg2gmYP8Qw,30088
21
+ hippius-0.2.23.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
22
+ hippius-0.2.23.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
23
+ hippius-0.2.23.dist-info/RECORD,,
hippius_sdk/__init__.py CHANGED
@@ -26,7 +26,7 @@ from hippius_sdk.config import (
26
26
  from hippius_sdk.ipfs import IPFSClient, S3PublishResult, S3DownloadResult
27
27
  from hippius_sdk.utils import format_cid, format_size, hex_to_ipfs_cid
28
28
 
29
- __version__ = "0.2.21"
29
+ __version__ = "0.2.23"
30
30
  __all__ = [
31
31
  "HippiusClient",
32
32
  "IPFSClient",
hippius_sdk/client.py CHANGED
@@ -517,7 +517,7 @@ class HippiusClient:
517
517
  encrypt: bool,
518
518
  seed_phrase: str,
519
519
  store_node: str = "http://localhost:5001",
520
- pin_node: str = "https://store.hippius.network"
520
+ pin_node: str = "https://store.hippius.network",
521
521
  ) -> S3PublishResult:
522
522
  """
523
523
  Publish a file to IPFS and the Hippius marketplace in one operation.
@@ -542,7 +542,9 @@ class HippiusClient:
542
542
  FileNotFoundError: If the file doesn't exist
543
543
  ValueError: If encryption is requested but not available
544
544
  """
545
- return await self.ipfs_client.s3_publish(file_path, encrypt, seed_phrase, store_node, pin_node)
545
+ return await self.ipfs_client.s3_publish(
546
+ file_path, encrypt, seed_phrase, store_node, pin_node
547
+ )
546
548
 
547
549
  async def s3_download(
548
550
  self,
@@ -550,7 +552,7 @@ class HippiusClient:
550
552
  output_path: str,
551
553
  seed_phrase: str,
552
554
  auto_decrypt: bool = True,
553
- download_node: str = "http://localhost:5001"
555
+ download_node: str = "http://localhost:5001",
554
556
  ) -> S3DownloadResult:
555
557
  """
556
558
  Download a file from IPFS with automatic decryption.
@@ -577,4 +579,6 @@ class HippiusClient:
577
579
  FileNotFoundError: If the output directory doesn't exist
578
580
  ValueError: If decryption fails
579
581
  """
580
- return await self.ipfs_client.s3_download(cid, output_path, seed_phrase, auto_decrypt, download_node)
582
+ return await self.ipfs_client.s3_download(
583
+ cid, output_path, seed_phrase, auto_decrypt, download_node
584
+ )
hippius_sdk/ipfs.py CHANGED
@@ -509,10 +509,18 @@ class IPFSClient:
509
509
  try:
510
510
  ls_result = await self.client.ls(cid)
511
511
  if isinstance(ls_result, dict) and ls_result.get("Objects", []):
512
- # Check if we have Links in the object, which means it's a directory
512
+ # Check if we have Links with non-empty names, which indicates a directory
513
+ # Links with empty names are file chunks, not directory entries
513
514
  for obj in ls_result["Objects"]:
514
- if obj.get("Links", []):
515
- is_directory = True
515
+ links = obj.get("Links", [])
516
+ if links:
517
+ # Check if any link has a non-empty name (directory entry)
518
+ # Links with empty names are file chunks, not directory entries
519
+ has_named_links = any(
520
+ link.get("Name", "").strip() for link in links
521
+ )
522
+ if has_named_links:
523
+ is_directory = True
516
524
  break
517
525
  except Exception:
518
526
  # If ls check fails, continue treating as a regular file
@@ -1932,7 +1940,7 @@ class IPFSClient:
1932
1940
  encrypt: bool,
1933
1941
  seed_phrase: str,
1934
1942
  store_node: str = "http://localhost:5001",
1935
- pin_node: str = "https://store.hippius.network"
1943
+ pin_node: str = "https://store.hippius.network",
1936
1944
  ) -> S3PublishResult:
1937
1945
  """
1938
1946
  Publish a file to IPFS and the Hippius marketplace in one operation.
@@ -2043,7 +2051,9 @@ class IPFSClient:
2043
2051
  cid = result["Hash"]
2044
2052
  logger.info(f"File uploaded to store node {store_node} with CID: {cid}")
2045
2053
  except Exception as e:
2046
- raise HippiusIPFSError(f"Failed to upload file to store node {store_node}: {str(e)}")
2054
+ raise HippiusIPFSError(
2055
+ f"Failed to upload file to store node {store_node}: {str(e)}"
2056
+ )
2047
2057
 
2048
2058
  # Step 2: Pin to pin_node (remote) for persistence and backup
2049
2059
  try:
@@ -2051,7 +2061,9 @@ class IPFSClient:
2051
2061
  await pin_client.pin(cid)
2052
2062
  logger.info(f"File pinned to backup node {pin_node}")
2053
2063
  except Exception as e:
2054
- raise HippiusIPFSError(f"Failed to pin file to store node {store_node}: {str(e)}")
2064
+ raise HippiusIPFSError(
2065
+ f"Failed to pin file to store node {store_node}: {str(e)}"
2066
+ )
2055
2067
 
2056
2068
  # Publish to substrate marketplace
2057
2069
  try:
@@ -2106,7 +2118,7 @@ class IPFSClient:
2106
2118
  output_path: str,
2107
2119
  seed_phrase: str,
2108
2120
  auto_decrypt: bool = True,
2109
- download_node: str = "http://localhost:5001"
2121
+ download_node: str = "http://localhost:5001",
2110
2122
  ) -> S3DownloadResult:
2111
2123
  """
2112
2124
  Download a file from IPFS with automatic decryption.
@@ -2153,7 +2165,9 @@ class IPFSClient:
2153
2165
  logger.info(f"File downloaded from {download_node} with CID: {cid}")
2154
2166
 
2155
2167
  except Exception as e:
2156
- raise HippiusIPFSError(f"Failed to download file from {download_node}: {str(e)}")
2168
+ raise HippiusIPFSError(
2169
+ f"Failed to download file from {download_node}: {str(e)}"
2170
+ )
2157
2171
 
2158
2172
  # Get file info after download
2159
2173
  size_bytes = os.path.getsize(output_path)
@@ -2184,8 +2198,12 @@ class IPFSClient:
2184
2198
  f"File may not exist on download node {download_node}. "
2185
2199
  f"Download URL: {download_url}"
2186
2200
  )
2187
- elif len(file_data) < 40: # PyNaCl encrypted data is at least 40 bytes (24-byte nonce + 16-byte auth tag + data)
2188
- logger.info(f"File too small to be encrypted ({len(file_data)} bytes), treating as plaintext")
2201
+ elif (
2202
+ len(file_data) < 40
2203
+ ): # PyNaCl encrypted data is at least 40 bytes (24-byte nonce + 16-byte auth tag + data)
2204
+ logger.info(
2205
+ f"File too small to be encrypted ({len(file_data)} bytes), treating as plaintext"
2206
+ )
2189
2207
  decrypted = False
2190
2208
  encryption_key_used = None
2191
2209
  else:
@@ -2199,7 +2217,9 @@ class IPFSClient:
2199
2217
  existing_key_b64 = await get_key_for_seed(seed_phrase)
2200
2218
 
2201
2219
  if existing_key_b64:
2202
- logger.debug("Found encryption key for seed phrase, attempting decryption")
2220
+ logger.debug(
2221
+ "Found encryption key for seed phrase, attempting decryption"
2222
+ )
2203
2223
  decryption_attempted = True
2204
2224
  encryption_key_used = existing_key_b64
2205
2225
 
@@ -2207,7 +2227,9 @@ class IPFSClient:
2207
2227
  try:
2208
2228
  import nacl.secret
2209
2229
 
2210
- encryption_key_bytes = base64.b64decode(existing_key_b64)
2230
+ encryption_key_bytes = base64.b64decode(
2231
+ existing_key_b64
2232
+ )
2211
2233
  box = nacl.secret.SecretBox(encryption_key_bytes)
2212
2234
  decrypted_data = box.decrypt(file_data)
2213
2235
 
@@ -2217,11 +2239,17 @@ class IPFSClient:
2217
2239
 
2218
2240
  decryption_successful = True
2219
2241
  decrypted = True
2220
- size_bytes = len(decrypted_data) # Update size to decrypted size
2221
- logger.info("Successfully decrypted file using stored key")
2242
+ size_bytes = len(
2243
+ decrypted_data
2244
+ ) # Update size to decrypted size
2245
+ logger.info(
2246
+ "Successfully decrypted file using stored key"
2247
+ )
2222
2248
 
2223
2249
  except Exception as decrypt_error:
2224
- logger.debug(f"Decryption failed with stored key: {decrypt_error}")
2250
+ logger.debug(
2251
+ f"Decryption failed with stored key: {decrypt_error}"
2252
+ )
2225
2253
  # Continue to try fallback decryption
2226
2254
  else:
2227
2255
  logger.debug("No encryption key found for seed phrase")
@@ -2243,7 +2271,9 @@ class IPFSClient:
2243
2271
 
2244
2272
  decryption_successful = True
2245
2273
  decrypted = True
2246
- size_bytes = len(decrypted_data) # Update size to decrypted size
2274
+ size_bytes = len(
2275
+ decrypted_data
2276
+ ) # Update size to decrypted size
2247
2277
 
2248
2278
  # Store the encryption key for the result
2249
2279
  encryption_key_used = (
@@ -2251,14 +2281,20 @@ class IPFSClient:
2251
2281
  if self.encryption_key
2252
2282
  else None
2253
2283
  )
2254
- logger.info("Successfully decrypted file using client encryption key")
2284
+ logger.info(
2285
+ "Successfully decrypted file using client encryption key"
2286
+ )
2255
2287
 
2256
2288
  except Exception as decrypt_error:
2257
- logger.debug(f"Decryption failed with client key: {decrypt_error}")
2289
+ logger.debug(
2290
+ f"Decryption failed with client key: {decrypt_error}"
2291
+ )
2258
2292
 
2259
2293
  # Log final decryption status
2260
2294
  if decryption_attempted and not decryption_successful:
2261
- logger.info("File may not be encrypted or decryption keys don't match")
2295
+ logger.info(
2296
+ "File may not be encrypted or decryption keys don't match"
2297
+ )
2262
2298
  elif not decryption_attempted:
2263
2299
  logger.debug("No decryption attempted - no keys available")
2264
2300
 
hippius_sdk/substrate.py CHANGED
@@ -1223,29 +1223,6 @@ class SubstrateClient:
1223
1223
  Returns:
1224
1224
  str: Transaction hash or status message
1225
1225
  """
1226
- # First check if this CID exists in the user's storage requests
1227
- try:
1228
- cid_exists = await self.check_storage_request_exists(cid)
1229
- if not cid_exists:
1230
- raise HippiusAlreadyDeletedError(
1231
- f"CID {cid} is not found in storage requests - may already be deleted"
1232
- )
1233
- except Exception as e:
1234
- if not isinstance(e, HippiusAlreadyDeletedError):
1235
- # If there was an error checking, but not our custom exception, wrap it
1236
- raise HippiusSubstrateConnectionError(
1237
- f"Error checking if CID exists: {str(e)}"
1238
- )
1239
- else:
1240
- # Re-raise our custom exception
1241
- raise
1242
-
1243
- # Continue with cancellation if it exists
1244
- if not self._ensure_keypair(seed_phrase):
1245
- raise HippiusSubstrateAuthError(
1246
- "Valid seed phrase must be provided or available in config"
1247
- )
1248
-
1249
1226
  # Initialize Substrate connection with seed phrase if needed
1250
1227
  if not self._substrate:
1251
1228
  self.connect(seed_phrase)