hippius 0.2.35__py3-none-any.whl → 0.2.37__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.35
3
+ Version: 0.2.37
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=TmGtNtxD9_iewlSe_hPs7ugnDJDcjQY6mD3V1dPh7v0,1474
1
+ hippius_sdk/__init__.py,sha256=FuqP1SPjpm3IjJbpPQtXE-1Q5HGju9bK-0TwDTy2uJY,1474
2
2
  hippius_sdk/cli.py,sha256=aqKOYSBSWt7UhcpFt7wf9yIPJ3bznpsJ6ehOnuZ4usI,18235
3
3
  hippius_sdk/cli_assets.py,sha256=rjH3Z5A1CQr2d5CIAAAb0WMCjoZZlMWcdo0f93KqluE,635
4
4
  hippius_sdk/cli_handlers.py,sha256=HkZldE8ZDS6WHu8aSoeS_rYZ4kp3F-Kdzu-weY1c0vU,128258
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=JIoKwq3YskuJO4YoRU8hJxVrCnk-t2oP6VDjEwZLIco,22666
7
+ hippius_sdk/client.py,sha256=aGnNdXMLUurqIvKZBbbASNg4yPXw_smfof9CQWPsr-4,22958
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
@@ -13,12 +13,12 @@ hippius_sdk/db/migrations/20241202000001_switch_to_subaccount_encryption.sql,sha
13
13
  hippius_sdk/db/setup_database.sh,sha256=STp03qxkp2RmIVr6YZIcvQQm-_LLUOb6Jobh-52HWmg,3115
14
14
  hippius_sdk/db_utils.py,sha256=-x0rbN0as7Tn3PJPZBYCgreZe52FLH40ppA1TLxsg90,1851
15
15
  hippius_sdk/errors.py,sha256=LScJJmawVAx7aRzqqQguYSkf9iazSjEQEBNlD_GXZ6Y,1589
16
- hippius_sdk/ipfs.py,sha256=22xHOrOer2KHvSMepaUNRMYAK04L-AKyv8sEPSAYg7g,95429
17
- hippius_sdk/ipfs_core.py,sha256=eOOgLoyP9mvwndnCjldnTc7z94ImYCXY3nm7JU3e_Mo,12676
16
+ hippius_sdk/ipfs.py,sha256=Gyow5xogdjV3W8uQzAxbvROw3tL3WZU-Zz7TtQdyHWs,96337
17
+ hippius_sdk/ipfs_core.py,sha256=X4yO9M_lSNtqiEJu5R-XX97eWzbL7GrN5MOk56p8pJk,12748
18
18
  hippius_sdk/key_storage.py,sha256=SXFd6aGQw9MDLGX2vSBuAY7rdX-k5EvFm63z7_n-8yQ,8148
19
19
  hippius_sdk/substrate.py,sha256=4a7UIE4UqGcDW7luKTBgSDqfb2OIZusB39G1UiRs_YU,50158
20
20
  hippius_sdk/utils.py,sha256=rJ611yvwKSyiBpYU3w-SuyQxoghMGU-ePuslrPv5H5g,7388
21
- hippius-0.2.35.dist-info/METADATA,sha256=u5_HkcKZ2mOZjPV4PO9P4ycVFaYxdmx4-rR5Gks2IyQ,30088
22
- hippius-0.2.35.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
23
- hippius-0.2.35.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
24
- hippius-0.2.35.dist-info/RECORD,,
21
+ hippius-0.2.37.dist-info/METADATA,sha256=abEkJKwKRWH1cq_mF1Yd_HoGggvKPqE19Y9HDWn9GBs,30088
22
+ hippius-0.2.37.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
23
+ hippius-0.2.37.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
24
+ hippius-0.2.37.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.35"
29
+ __version__ = "0.2.37"
30
30
  __all__ = [
31
31
  "HippiusClient",
32
32
  "IPFSClient",
hippius_sdk/client.py CHANGED
@@ -521,6 +521,7 @@ class HippiusClient:
521
521
  encrypt: bool,
522
522
  seed_phrase: str,
523
523
  subaccount_id: str,
524
+ bucket_name: str,
524
525
  store_node: str = "http://localhost:5001",
525
526
  pin_node: str = "https://store.hippius.network",
526
527
  substrate_url: str = "wss://rpc.hippius.network",
@@ -536,6 +537,8 @@ class HippiusClient:
536
537
  file_path: Path to the file to publish
537
538
  encrypt: Whether to encrypt the file before uploading
538
539
  seed_phrase: Seed phrase for blockchain transaction signing
540
+ subaccount_id: The subaccount/account identifier
541
+ bucket_name: The bucket name for key isolation
539
542
  store_node: IPFS node URL for initial upload (default: local node)
540
543
  pin_node: IPFS node URL for backup pinning (default: remote service)
541
544
  substrate_url: substrate url to use for the storage request.
@@ -554,6 +557,7 @@ class HippiusClient:
554
557
  encrypt,
555
558
  seed_phrase,
556
559
  subaccount_id,
560
+ bucket_name,
557
561
  store_node,
558
562
  pin_node,
559
563
  substrate_url,
@@ -564,6 +568,7 @@ class HippiusClient:
564
568
  cid: str,
565
569
  output_path: str,
566
570
  subaccount_id: str,
571
+ bucket_name: str,
567
572
  auto_decrypt: bool = True,
568
573
  download_node: str = "http://localhost:5001",
569
574
  ) -> S3DownloadResult:
@@ -571,16 +576,17 @@ class HippiusClient:
571
576
  Download a file from IPFS with automatic decryption.
572
577
 
573
578
  This method uses the download_node for immediate availability and automatically
574
- manages decryption keys per seed phrase:
579
+ manages decryption keys per account+bucket combination:
575
580
  - Downloads the file from the specified download_node (local by default)
576
- - If auto_decrypt=True, attempts to decrypt using stored keys for the seed phrase
581
+ - If auto_decrypt=True, attempts to decrypt using stored keys for the account+bucket
577
582
  - Falls back to client encryption key if key storage is not available
578
583
  - Returns the file in decrypted form if decryption succeeds
579
584
 
580
585
  Args:
581
586
  cid: Content Identifier (CID) of the file to download
582
587
  output_path: Path where the downloaded file will be saved
583
- subaccount_id: The subaccount id as api key
588
+ subaccount_id: The subaccount/account identifier
589
+ bucket_name: The bucket name for key isolation
584
590
  auto_decrypt: Whether to attempt automatic decryption (default: True)
585
591
  download_node: IPFS node URL for download (default: local node)
586
592
 
@@ -593,5 +599,5 @@ class HippiusClient:
593
599
  ValueError: If decryption fails
594
600
  """
595
601
  return await self.ipfs_client.s3_download(
596
- cid, output_path, subaccount_id, auto_decrypt, download_node
602
+ cid, output_path, subaccount_id, bucket_name, auto_decrypt, download_node
597
603
  )
hippius_sdk/ipfs.py CHANGED
@@ -1954,6 +1954,7 @@ class IPFSClient:
1954
1954
  encrypt: bool,
1955
1955
  seed_phrase: str,
1956
1956
  subaccount_id: str,
1957
+ bucket_name: str,
1957
1958
  store_node: str = "http://localhost:5001",
1958
1959
  pin_node: str = "https://store.hippius.network",
1959
1960
  substrate_url: str = "wss://rpc.hippius.network",
@@ -1966,15 +1967,17 @@ class IPFSClient:
1966
1967
  2. Pins to pin_node (remote) for persistence and backup
1967
1968
  3. Publishes to substrate marketplace
1968
1969
 
1969
- This method automatically manages encryption keys per seed phrase:
1970
- - If encrypt=True, it will get or generate an encryption key for the seed phrase
1970
+ This method automatically manages encryption keys per account+bucket combination:
1971
+ - If encrypt=True, it will get or generate an encryption key for the account+bucket
1971
1972
  - Keys are stored in PostgreSQL and versioned (never deleted)
1972
- - Always uses the most recent key for a seed phrase
1973
+ - Always uses the most recent key for an account+bucket combination
1973
1974
 
1974
1975
  Args:
1975
1976
  file_path: Path to the file to publish
1976
1977
  encrypt: Whether to encrypt the file before uploading
1977
1978
  seed_phrase: Seed phrase for blockchain transaction signing
1979
+ subaccount_id: The subaccount/account identifier
1980
+ bucket_name: The bucket name for key isolation
1978
1981
  store_node: IPFS node URL for initial upload (default: local node)
1979
1982
  pin_node: IPFS node URL for backup pinning (default: remote service)
1980
1983
  substrate_url: the substrate url to connect to for the storage request.
@@ -2008,19 +2011,26 @@ class IPFSClient:
2008
2011
  key_storage_available = False
2009
2012
 
2010
2013
  if key_storage_available:
2011
- # Try to get existing key for this seed phrase
2012
- existing_key_b64 = await get_key_for_subaccount(subaccount_id)
2014
+ # Create combined key identifier from account+bucket
2015
+ account_bucket_key = f"{subaccount_id}:{bucket_name}"
2016
+
2017
+ # Try to get existing key for this account+bucket combination
2018
+ existing_key_b64 = await get_key_for_subaccount(account_bucket_key)
2013
2019
 
2014
2020
  if existing_key_b64:
2015
2021
  # Use existing key
2016
- logger.debug("Using existing encryption key for subaccount")
2022
+ logger.debug(
2023
+ "Using existing encryption key for account+bucket combination"
2024
+ )
2017
2025
  encryption_key_bytes = base64.b64decode(existing_key_b64)
2018
2026
  encryption_key_used = existing_key_b64
2019
2027
  else:
2020
- # Generate and store new key for this subaccount
2021
- logger.info("Generating new encryption key for subaccount")
2028
+ # Generate and store new key for this account+bucket combination
2029
+ logger.info(
2030
+ "Generating new encryption key for account+bucket combination"
2031
+ )
2022
2032
  new_key_b64 = await generate_and_store_key_for_subaccount(
2023
- subaccount_id
2033
+ account_bucket_key
2024
2034
  )
2025
2035
  encryption_key_bytes = base64.b64decode(new_key_b64)
2026
2036
  encryption_key_used = new_key_b64
@@ -2138,6 +2148,7 @@ class IPFSClient:
2138
2148
  cid: str,
2139
2149
  output_path: str,
2140
2150
  subaccount_id: str,
2151
+ bucket_name: str,
2141
2152
  auto_decrypt: bool = True,
2142
2153
  download_node: str = "http://localhost:5001",
2143
2154
  ) -> S3DownloadResult:
@@ -2145,16 +2156,17 @@ class IPFSClient:
2145
2156
  Download a file from IPFS with automatic decryption.
2146
2157
 
2147
2158
  This method uses the download_node for immediate availability and automatically
2148
- manages decryption keys per seed phrase:
2159
+ manages decryption keys per account+bucket combination:
2149
2160
  - Downloads the file from the specified download_node (local by default)
2150
- - If auto_decrypt=True, attempts to decrypt using stored keys for the seed phrase
2161
+ - If auto_decrypt=True, attempts to decrypt using stored keys for the account+bucket
2151
2162
  - Falls back to client encryption key if key storage is not available
2152
2163
  - Returns the file in decrypted form if decryption succeeds
2153
2164
 
2154
2165
  Args:
2155
2166
  cid: Content Identifier (CID) of the file to download
2156
2167
  output_path: Path where the downloaded file will be saved
2157
- subaccount_id: The subaccount id as api key
2168
+ subaccount_id: The subaccount/account identifier
2169
+ bucket_name: The bucket name for key isolation
2158
2170
  auto_decrypt: Whether to attempt automatic decryption (default: True)
2159
2171
  download_node: IPFS node URL for download (default: local node)
2160
2172
 
@@ -2233,13 +2245,18 @@ class IPFSClient:
2233
2245
  decryption_successful = False
2234
2246
 
2235
2247
  if key_storage_available:
2236
- # Try to get the encryption key for this seed phrase
2248
+ # Create combined key identifier from account+bucket
2249
+ account_bucket_key = f"{subaccount_id}:{bucket_name}"
2250
+
2251
+ # Try to get the encryption key for this account+bucket combination
2237
2252
  try:
2238
- existing_key_b64 = await get_key_for_subaccount(subaccount_id)
2253
+ existing_key_b64 = await get_key_for_subaccount(
2254
+ account_bucket_key
2255
+ )
2239
2256
 
2240
2257
  if existing_key_b64:
2241
2258
  logger.debug(
2242
- "Found encryption key for subaccount, attempting decryption"
2259
+ "Found encryption key for account+bucket combination, attempting decryption"
2243
2260
  )
2244
2261
  decryption_attempted = True
2245
2262
  encryption_key_used = existing_key_b64
@@ -2273,7 +2290,9 @@ class IPFSClient:
2273
2290
  )
2274
2291
  # Continue to try fallback decryption
2275
2292
  else:
2276
- logger.debug("No encryption key found for seed phrase")
2293
+ logger.debug(
2294
+ "No encryption key found for account+bucket combination"
2295
+ )
2277
2296
 
2278
2297
  except Exception as e:
2279
2298
  logger.debug(f"Error retrieving key from storage: {e}")
hippius_sdk/ipfs_core.py CHANGED
@@ -65,7 +65,8 @@ class AsyncIPFSClient:
65
65
  files = {"file": (filename, file_content, "application/octet-stream")}
66
66
  # Explicitly set wrap-with-directory=false to prevent wrapping in directory
67
67
  response = await self.client.post(
68
- f"{self.api_url}/api/v0/add?wrap-with-directory=false", files=files
68
+ f"{self.api_url}/api/v0/add?wrap-with-directory=false&cid-version=1",
69
+ files=files,
69
70
  )
70
71
  response.raise_for_status()
71
72
  return response.json()
@@ -85,7 +86,8 @@ class AsyncIPFSClient:
85
86
  files = {"file": (filename, data, "application/octet-stream")}
86
87
  # Explicitly set wrap-with-directory=false to prevent wrapping in directory
87
88
  response = await self.client.post(
88
- f"{self.api_url}/api/v0/add?wrap-with-directory=false", files=files
89
+ f"{self.api_url}/api/v0/add?wrap-with-directory=false&cid-version=1",
90
+ files=files,
89
91
  )
90
92
  response.raise_for_status()
91
93
  return response.json()
@@ -346,7 +348,7 @@ class AsyncIPFSClient:
346
348
 
347
349
  # Make the request with directory flags
348
350
  response = await self.client.post(
349
- f"{self.api_url}/api/v0/add?recursive=true&wrap-with-directory=true",
351
+ f"{self.api_url}/api/v0/add?recursive=true&wrap-with-directory=true&cid-version=1",
350
352
  files=files,
351
353
  timeout=300.0, # 5 minute timeout for directory uploads
352
354
  )