sgx.py 0.11.dev1__tar.gz → 0.12.dev1__tar.gz

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.
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: sgx.py
3
+ Version: 0.12.dev1
4
+ Summary: SGX
5
+ Home-page: http://github.com/skalenetwork/sgx.py
6
+ Author: SKALE Labs
7
+ Author-email: support@skalelabs.com
8
+ Requires-Python: >=3.11,<4
9
+ License-File: LICENSE
10
+ Requires-Dist: cryptography<51,>=50.0.2
11
+ Requires-Dist: cytoolz>=0.12
12
+ Requires-Dist: eth-account<0.15,>=0.13
13
+ Requires-Dist: eth-hash[pycryptodome]>=0.7
14
+ Requires-Dist: eth-utils<7,>=5
15
+ Requires-Dist: hexbytes<3,>=1
16
+ Requires-Dist: pem==23.1.0
17
+ Requires-Dist: pyzmq==27.2.0
18
+ Requires-Dist: requests>=2.33.0
19
+ Requires-Dist: urllib3>=2.8.0
20
+ Provides-Extra: linter
21
+ Requires-Dist: ruff==0.17.2; extra == "linter"
22
+ Provides-Extra: dev
23
+ Requires-Dist: ruff==0.17.2; extra == "dev"
24
+ Requires-Dist: build==1.6.1; extra == "dev"
25
+ Requires-Dist: coincurve==13.0.0; extra == "dev"
26
+ Requires-Dist: python-dotenv==1.2.4; extra == "dev"
27
+ Requires-Dist: twine==7.0.0; extra == "dev"
28
+ Requires-Dist: pytest==9.1.1; extra == "dev"
29
+ Requires-Dist: mock==5.2.0; extra == "dev"
30
+ Requires-Dist: web3==8.0.0; extra == "dev"
31
+ Dynamic: author
32
+ Dynamic: author-email
33
+ Dynamic: home-page
34
+ Dynamic: license-file
35
+ Dynamic: provides-extra
36
+ Dynamic: requires-dist
37
+ Dynamic: requires-python
38
+ Dynamic: summary
@@ -5,14 +5,16 @@ from setuptools import (
5
5
 
6
6
  extras_require = {
7
7
  'linter': [
8
- 'ruff==0.13.2',
8
+ 'ruff==0.17.2',
9
9
  ],
10
10
  'dev': [
11
+ 'build==1.6.1',
11
12
  'coincurve==13.0.0',
12
- 'python-dotenv==0.13.0',
13
- 'twine==6.2.0',
14
- 'pytest==8.4.2',
13
+ 'python-dotenv==1.2.4',
14
+ 'twine==7.0.0',
15
+ 'pytest==9.1.1',
15
16
  'mock==5.2.0',
17
+ 'web3==8.0.0',
16
18
  ],
17
19
  }
18
20
 
@@ -20,16 +22,22 @@ extras_require['dev'] = extras_require['linter'] + extras_require['dev']
20
22
 
21
23
  setup(
22
24
  name='sgx.py',
23
- version='0.11dev1',
25
+ version='0.12dev1',
24
26
  description='SGX',
25
27
  url='http://github.com/skalenetwork/sgx.py',
26
28
  author='SKALE Labs',
27
29
  author_email='support@skalelabs.com',
28
30
  install_requires=[
29
- 'web3>=6.20.2,<8.0.0',
30
- 'pyzmq==27.1.0',
31
+ 'cryptography>=50.0.2,<51',
32
+ 'cytoolz>=0.12',
33
+ 'eth-account>=0.13,<0.15',
34
+ 'eth-hash[pycryptodome]>=0.7',
35
+ 'eth-utils>=5,<7',
36
+ 'hexbytes>=1,<3',
31
37
  'pem==23.1.0',
32
- 'cryptography>=46.0.1,<47.0.0',
38
+ 'pyzmq==27.2.0',
39
+ 'requests>=2.33.0',
40
+ 'urllib3>=2.8.0',
33
41
  ],
34
42
  packages=find_packages(exclude=['tests']),
35
43
  python_requires='>=3.11,<4',
@@ -10,3 +10,4 @@ SGX_ZMQ_RESPONSE_TIMEOUT_MS = 5000
10
10
  CSR_FILENAME = 'sgx.csr'
11
11
  KEY_FILENAME = 'sgx.key'
12
12
  CRT_FILENAME = 'sgx.crt'
13
+ LOCK_FILENAME = 'sgx.enroll.lock'
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+ umask 077
5
+
6
+ CSR_PATH="$1"
7
+ KEY_PATH="$2"
8
+ COMMON_NAME="$3"
9
+
10
+ rm -f -- "$CSR_PATH" "$KEY_PATH"
11
+
12
+ openssl req -new -sha256 -nodes \
13
+ -out "$CSR_PATH" \
14
+ -newkey rsa:2048 \
15
+ -keyout "$KEY_PATH" \
16
+ -subj "/CN=$COMMON_NAME"
17
+
18
+ chmod 600 "$KEY_PATH"
@@ -1,29 +1,33 @@
1
- import os
1
+ import fcntl
2
+ import json
2
3
  import logging
4
+ import os
3
5
  import secrets
4
- import requests
5
- import json
6
+ from contextlib import contextmanager
6
7
  from time import sleep
7
8
  from urllib.parse import urlparse
8
9
 
10
+ import requests
9
11
  import urllib3
10
12
  from requests.packages.urllib3.exceptions import InsecureRequestWarning
13
+
11
14
  from sgx.constants import (
12
- GENERATE_SCRIPT_PATH,
13
- DEFAULT_TIMEOUT,
14
- CSR_FILENAME,
15
15
  CRT_FILENAME,
16
+ CSR_FILENAME,
17
+ DEFAULT_TIMEOUT,
18
+ GENERATE_SCRIPT_PATH,
16
19
  KEY_FILENAME,
17
- SGX_RESPONSE_TIMEOUT
20
+ LOCK_FILENAME,
21
+ SGX_RESPONSE_TIMEOUT,
18
22
  )
19
- from sgx.utils import run_cmd, print_request_log, print_response_log, SgxError
20
-
23
+ from sgx.utils import SgxError, print_request_log, print_response_log, run_cmd
21
24
 
22
25
  requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # TODO: Remove
23
26
  logger = logging.getLogger(__name__)
24
27
 
25
28
 
26
29
  MAX_RETRIES = 22
30
+ CSR_STATUS_PENDING = 1
27
31
 
28
32
 
29
33
  class SgxSSLError(SgxError):
@@ -34,15 +38,36 @@ class SgxUnreachableError(SgxError):
34
38
  pass
35
39
 
36
40
 
41
+ def certificate_exists(crt_dir_path: str) -> bool:
42
+ return all(
43
+ os.path.exists(os.path.join(crt_dir_path, filename))
44
+ for filename in (CRT_FILENAME, KEY_FILENAME)
45
+ )
46
+
47
+
48
+ @contextmanager
49
+ def enrollment_lock(crt_dir_path: str):
50
+ lock_path = os.path.join(crt_dir_path, LOCK_FILENAME)
51
+ fd = os.open(lock_path, os.O_CREAT | os.O_RDWR, 0o600)
52
+ try:
53
+ fcntl.flock(fd, fcntl.LOCK_EX)
54
+ yield
55
+ finally:
56
+ os.close(fd)
57
+
58
+
37
59
  def get_certificate_credentials(crt_dir_path, csr_server):
38
60
  key_path = os.path.join(crt_dir_path, KEY_FILENAME)
39
61
  crt_path = os.path.join(crt_dir_path, CRT_FILENAME)
40
- if not os.path.exists(crt_path) or not os.path.exists(key_path):
41
- csr_path = os.path.join(crt_dir_path, CSR_FILENAME)
42
- if not os.path.exists(csr_path) or not os.path.exists(key_path):
43
- generate_csr_credentials(csr_path, key_path)
44
- csr_hash = sign_certificate(csr_server, csr_path)
45
- write_crt_to_file(crt_path, csr_server, csr_hash)
62
+ if certificate_exists(crt_dir_path):
63
+ return crt_path, key_path
64
+ with enrollment_lock(crt_dir_path):
65
+ if not certificate_exists(crt_dir_path):
66
+ csr_path = os.path.join(crt_dir_path, CSR_FILENAME)
67
+ if not os.path.exists(csr_path) or not os.path.exists(key_path):
68
+ generate_csr_credentials(csr_path, key_path)
69
+ csr_hash = sign_certificate(csr_server, csr_path)
70
+ write_crt_to_file(crt_path, csr_server, csr_hash)
46
71
  return crt_path, key_path
47
72
 
48
73
 
@@ -52,13 +77,23 @@ def generate_csr_credentials(csr_path, key_path):
52
77
 
53
78
 
54
79
  def write_crt_to_file(crt_path, csr_server, csr_hash):
55
- response = send_request_safe(csr_server, 'getCertificate', {'hash': csr_hash})
56
- while response['result']['status'] == 1:
57
- response = send_request_safe(csr_server, 'getCertificate', {'hash': csr_hash})
58
- sleep(DEFAULT_TIMEOUT)
59
- crt = response['result']['cert']
60
- with open(crt_path, "w+") as f:
61
- f.write(crt)
80
+ for _ in range(MAX_RETRIES):
81
+ response = send_request(csr_server, 'getCertificate', {'hash': csr_hash})
82
+ if response.get('error'):
83
+ raise SgxSSLError(response['error']['message'])
84
+ result = response['result']
85
+ if result['status'] == CSR_STATUS_PENDING:
86
+ sleep(DEFAULT_TIMEOUT)
87
+ continue
88
+ if result['status'] != 0:
89
+ raise SgxSSLError(result['errorMessage'])
90
+ with open(crt_path, 'w') as f:
91
+ f.write(result['cert'])
92
+ return
93
+ raise SgxSSLError(
94
+ f'Certificate signing request {csr_hash} is still pending '
95
+ f'after {MAX_RETRIES} attempts'
96
+ )
62
97
 
63
98
 
64
99
  def sign_certificate(csr_server, csr_path):
@@ -18,20 +18,22 @@
18
18
  # along with sgx.py. If not, see <https://www.gnu.org/licenses/>.
19
19
 
20
20
  import logging
21
- from dataclasses import dataclass
22
21
  from collections.abc import Mapping
23
- from hexbytes import HexBytes
24
- from eth_account.datastructures import SignedTransaction, SignedMessage
25
- from eth_utils.curried import keccak
22
+ from dataclasses import dataclass
23
+
26
24
  from cytoolz import dissoc
27
- from sgx.sgx_rpc_handler import SgxRPCHandler
28
- from sgx.sgx_zmq import SgxZmq
29
- from sgx.utils import public_key_to_address
30
25
  from eth_account._utils import signing
31
26
  from eth_account._utils.legacy_transactions import encode_transaction
27
+ from eth_account.datastructures import SignedMessage, SignedTransaction
32
28
  from eth_account.typed_transactions.typed_transaction import TypedTransaction
33
- from eth_utils.encoding import big_endian_to_int
34
29
  from eth_utils.conversions import add_0x_prefix, remove_0x_prefix
30
+ from eth_utils.curried import keccak
31
+ from eth_utils.encoding import big_endian_to_int
32
+ from hexbytes import HexBytes
33
+
34
+ from sgx.sgx_rpc_handler import SgxRPCHandler
35
+ from sgx.sgx_zmq import SgxZmq
36
+ from sgx.utils import public_key_to_address
35
37
 
36
38
  logger = logging.getLogger(__name__)
37
39
 
@@ -18,15 +18,12 @@
18
18
  # along with sgx.py. If not, see <https://www.gnu.org/licenses/>.
19
19
 
20
20
  import logging
21
- import os
22
21
  from enum import Enum
23
-
24
22
  from urllib.parse import urlparse
25
23
 
26
- from sgx.http import send_request
24
+ from sgx.http import certificate_exists, send_request
27
25
  from sgx.utils import SgxError
28
26
 
29
-
30
27
  logger = logging.getLogger(__name__)
31
28
 
32
29
 
@@ -44,7 +41,7 @@ class SgxRPCHandler:
44
41
  def __init__(self, sgx_endpoint, path_to_cert):
45
42
  self.sgx_endpoint = check_provider(sgx_endpoint)
46
43
  self.path_to_cert = path_to_cert
47
- if path_to_cert and len(os.listdir(path_to_cert)) != 3:
44
+ if path_to_cert and not certificate_exists(path_to_cert):
48
45
  self.get_server_status()
49
46
 
50
47
  def ecdsa_sign(self, key_name, transaction_hash):
@@ -179,7 +176,9 @@ class SgxRPCHandler:
179
176
  response = self.__send_request("createBLSPrivateKeyV2", params)
180
177
  return response['result']['status'] == 0
181
178
 
182
- def create_bls_private_key_v3(self, poly_name, bls_key_name, eth_key_name, secret_contributions, n, t):
179
+ def create_bls_private_key_v3(
180
+ self, poly_name, bls_key_name, eth_key_name, secret_contributions, n, t
181
+ ):
183
182
  params = dict()
184
183
  # polyName is optional in V3 - new nodes joining the network do not pass it
185
184
  if poly_name:
@@ -24,20 +24,17 @@ import os
24
24
  from dataclasses import dataclass
25
25
  from enum import Enum
26
26
  from time import sleep
27
- from sgx.utils import public_key_to_address
27
+ from urllib.parse import urlparse
28
28
 
29
- from eth_utils.conversions import add_0x_prefix, remove_0x_prefix
30
29
  import pem
31
30
  import zmq
32
31
  from cryptography.hazmat.primitives import hashes
33
- from cryptography.hazmat.primitives.asymmetric import ec, rsa, padding
32
+ from cryptography.hazmat.primitives.asymmetric import ec, padding, rsa
34
33
  from cryptography.hazmat.primitives.serialization import load_pem_private_key
34
+ from eth_utils.conversions import add_0x_prefix, remove_0x_prefix
35
35
 
36
- from urllib.parse import urlparse
37
-
38
- from sgx.constants import DEFAULT_TIMEOUT, SGX_ZMQ_RESPONSE_TIMEOUT_MS, CRT_FILENAME, KEY_FILENAME
39
- from sgx.utils import SgxError
40
-
36
+ from sgx.constants import CRT_FILENAME, DEFAULT_TIMEOUT, KEY_FILENAME, SGX_ZMQ_RESPONSE_TIMEOUT_MS
37
+ from sgx.utils import SgxError, public_key_to_address
41
38
 
42
39
  logger = logging.getLogger(__name__)
43
40
 
@@ -291,7 +288,6 @@ class SgxZmq:
291
288
  p_id = os.getpid()
292
289
  if not self.sockets.get(p_id):
293
290
  socket_p_id = self.ctx.socket(zmq.DEALER)
294
- socket_p_id.setsockopt_string(zmq.IDENTITY, '135:14603077656239261618')
295
291
  socket_p_id.setsockopt(zmq.LINGER, 0)
296
292
  socket_p_id.setsockopt(zmq.SNDTIMEO, SGX_ZMQ_RESPONSE_TIMEOUT_MS)
297
293
  socket_p_id.setsockopt(zmq.RCVTIMEO, SGX_ZMQ_RESPONSE_TIMEOUT_MS)
@@ -18,48 +18,55 @@
18
18
  # along with sgx.py. If not, see <https://www.gnu.org/licenses/>.
19
19
 
20
20
 
21
- import copy
22
21
  import logging
23
22
  import os
24
23
  import subprocess
25
24
  from subprocess import PIPE
26
25
 
27
- from web3 import Web3
28
-
26
+ from eth_utils import keccak, to_checksum_address, to_hex
29
27
 
30
28
  logger = logging.getLogger(__name__)
31
29
 
30
+ REDACTED = '<redacted>'
31
+ SECRET_FIELDS = frozenset({
32
+ 'dhKey',
33
+ 'key',
34
+ 'keyShare',
35
+ 'secretContributions',
36
+ 'secretShare',
37
+ })
38
+
32
39
 
33
40
  class SgxError(Exception):
34
41
  pass
35
42
 
36
43
 
37
- def crop_json(json_data, crop_len=50):
38
- for key, value in json_data.items():
39
- if isinstance(value, dict):
40
- crop_json(value)
41
- else:
42
- if isinstance(value, str) and len(value) > crop_len:
43
- json_data[key] = value[:crop_len] + '...'
44
+ def redact(data: object, crop_len: int = 50) -> object:
45
+ if isinstance(data, dict):
46
+ return {
47
+ key: REDACTED if key in SECRET_FIELDS else redact(value, crop_len)
48
+ for key, value in data.items()
49
+ }
50
+ if isinstance(data, list):
51
+ return [redact(item, crop_len) for item in data]
52
+ if isinstance(data, str) and len(data) > crop_len:
53
+ return data[:crop_len] + '...'
54
+ return data
44
55
 
45
56
 
46
57
  def print_request_log(request):
47
- cropped_request = copy.deepcopy(request)
48
- crop_json(cropped_request)
49
- logger.info(f'Send request: {request}')
58
+ logger.info(f'Send request: {redact(request)}')
50
59
 
51
60
 
52
61
  def print_response_log(response):
53
- cropped_response = copy.deepcopy(response)
54
- crop_json(cropped_response)
55
- logger.info(f'Response received: {cropped_response}')
62
+ logger.info(f'Response received: {redact(response)}')
56
63
 
57
64
 
58
- def run_cmd(cmd, env={}, shell=False):
65
+ def run_cmd(cmd, env=None, shell=False):
59
66
  logger.info(f'Running: {cmd}')
60
67
  res = subprocess.run(
61
68
  cmd, shell=shell, stdout=PIPE, stderr=PIPE,
62
- env={**env, **os.environ}
69
+ env={**os.environ, **(env or {})}
63
70
  )
64
71
  if res.returncode:
65
72
  logger.error('Error during shell execution:')
@@ -69,5 +76,5 @@ def run_cmd(cmd, env={}, shell=False):
69
76
 
70
77
 
71
78
  def public_key_to_address(pk):
72
- hash_ = Web3.keccak(hexstr=str(pk))
73
- return Web3.to_checksum_address(Web3.to_hex(hash_[-20:]))
79
+ hash_ = keccak(hexstr=str(pk))
80
+ return to_checksum_address(to_hex(hash_[-20:]))
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: sgx.py
3
+ Version: 0.12.dev1
4
+ Summary: SGX
5
+ Home-page: http://github.com/skalenetwork/sgx.py
6
+ Author: SKALE Labs
7
+ Author-email: support@skalelabs.com
8
+ Requires-Python: >=3.11,<4
9
+ License-File: LICENSE
10
+ Requires-Dist: cryptography<51,>=50.0.2
11
+ Requires-Dist: cytoolz>=0.12
12
+ Requires-Dist: eth-account<0.15,>=0.13
13
+ Requires-Dist: eth-hash[pycryptodome]>=0.7
14
+ Requires-Dist: eth-utils<7,>=5
15
+ Requires-Dist: hexbytes<3,>=1
16
+ Requires-Dist: pem==23.1.0
17
+ Requires-Dist: pyzmq==27.2.0
18
+ Requires-Dist: requests>=2.33.0
19
+ Requires-Dist: urllib3>=2.8.0
20
+ Provides-Extra: linter
21
+ Requires-Dist: ruff==0.17.2; extra == "linter"
22
+ Provides-Extra: dev
23
+ Requires-Dist: ruff==0.17.2; extra == "dev"
24
+ Requires-Dist: build==1.6.1; extra == "dev"
25
+ Requires-Dist: coincurve==13.0.0; extra == "dev"
26
+ Requires-Dist: python-dotenv==1.2.4; extra == "dev"
27
+ Requires-Dist: twine==7.0.0; extra == "dev"
28
+ Requires-Dist: pytest==9.1.1; extra == "dev"
29
+ Requires-Dist: mock==5.2.0; extra == "dev"
30
+ Requires-Dist: web3==8.0.0; extra == "dev"
31
+ Dynamic: author
32
+ Dynamic: author-email
33
+ Dynamic: home-page
34
+ Dynamic: license-file
35
+ Dynamic: provides-extra
36
+ Dynamic: requires-dist
37
+ Dynamic: requires-python
38
+ Dynamic: summary
@@ -0,0 +1,23 @@
1
+ cryptography<51,>=50.0.2
2
+ cytoolz>=0.12
3
+ eth-account<0.15,>=0.13
4
+ eth-hash[pycryptodome]>=0.7
5
+ eth-utils<7,>=5
6
+ hexbytes<3,>=1
7
+ pem==23.1.0
8
+ pyzmq==27.2.0
9
+ requests>=2.33.0
10
+ urllib3>=2.8.0
11
+
12
+ [dev]
13
+ ruff==0.17.2
14
+ build==1.6.1
15
+ coincurve==13.0.0
16
+ python-dotenv==1.2.4
17
+ twine==7.0.0
18
+ pytest==9.1.1
19
+ mock==5.2.0
20
+ web3==8.0.0
21
+
22
+ [linter]
23
+ ruff==0.17.2
@@ -1,22 +1,18 @@
1
- import urllib
2
1
  import os
3
2
  import secrets
3
+ import socket
4
+ import urllib
4
5
 
5
6
  import eth_account._utils.legacy_transactions as transactions
6
7
  import pytest
7
-
8
- from eth_account.messages import defunct_hash_message, encode_defunct
9
-
10
8
  from dotenv import load_dotenv
9
+ from eth_account.messages import defunct_hash_message, encode_defunct
11
10
  from eth_keys import keys
12
11
  from hexbytes import HexBytes
13
- import socket
14
12
  from web3 import Web3
15
13
 
16
-
17
14
  from sgx import SgxClient
18
15
 
19
-
20
16
  load_dotenv()
21
17
 
22
18
  SGX_URL = os.getenv('SERVER')
@@ -1,14 +1,16 @@
1
- from sgx import SgxClient
2
- from sgx.sgx_rpc_handler import SgxServerError
3
- from sgx.sgx_zmq import SgxZmqServerError
1
+ import binascii
2
+ import hashlib
4
3
  import os
5
- from time import sleep
6
- from dotenv import load_dotenv
7
4
  import random
8
- import coincurve
9
- import binascii
10
5
  import secrets
11
- import hashlib
6
+ from time import sleep
7
+
8
+ import coincurve
9
+ from dotenv import load_dotenv
10
+
11
+ from sgx import SgxClient
12
+ from sgx.sgx_rpc_handler import SgxServerError
13
+ from sgx.sgx_zmq import SgxZmqServerError
12
14
 
13
15
  load_dotenv()
14
16
 
@@ -3,8 +3,7 @@ import pytest
3
3
  import requests
4
4
  import urllib3
5
5
 
6
- from sgx.http import send_request
7
- from sgx.http import SgxUnreachableError
6
+ from sgx.http import SgxUnreachableError, send_request
8
7
 
9
8
  URL = 'http://127.0.0.1:1026'
10
9
  INVALID_URL = 'http://127.0.0.1:1033'
sgx_py-0.11.dev1/PKG-INFO DELETED
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: sgx.py
3
- Version: 0.11.dev1
4
- Summary: SGX
5
- Home-page: http://github.com/skalenetwork/sgx.py
6
- Author: SKALE Labs
7
- Author-email: support@skalelabs.com
8
- Requires-Python: >=3.11,<4
9
- License-File: LICENSE
10
- Requires-Dist: web3<8.0.0,>=6.20.2
11
- Requires-Dist: pyzmq==27.1.0
12
- Requires-Dist: pem==23.1.0
13
- Requires-Dist: cryptography<47.0.0,>=46.0.1
14
- Provides-Extra: linter
15
- Requires-Dist: ruff==0.13.2; extra == "linter"
16
- Provides-Extra: dev
17
- Requires-Dist: ruff==0.13.2; extra == "dev"
18
- Requires-Dist: coincurve==13.0.0; extra == "dev"
19
- Requires-Dist: python-dotenv==0.13.0; extra == "dev"
20
- Requires-Dist: twine==6.2.0; extra == "dev"
21
- Requires-Dist: pytest==8.4.2; extra == "dev"
22
- Requires-Dist: mock==5.2.0; extra == "dev"
23
- Dynamic: author
24
- Dynamic: author-email
25
- Dynamic: home-page
26
- Dynamic: license-file
27
- Dynamic: provides-extra
28
- Dynamic: requires-dist
29
- Dynamic: requires-python
30
- Dynamic: summary
@@ -1 +0,0 @@
1
- openssl req -new -sha256 -nodes -out $1 -newkey rsa:2048 -keyout $2 -subj /CN=$3
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: sgx.py
3
- Version: 0.11.dev1
4
- Summary: SGX
5
- Home-page: http://github.com/skalenetwork/sgx.py
6
- Author: SKALE Labs
7
- Author-email: support@skalelabs.com
8
- Requires-Python: >=3.11,<4
9
- License-File: LICENSE
10
- Requires-Dist: web3<8.0.0,>=6.20.2
11
- Requires-Dist: pyzmq==27.1.0
12
- Requires-Dist: pem==23.1.0
13
- Requires-Dist: cryptography<47.0.0,>=46.0.1
14
- Provides-Extra: linter
15
- Requires-Dist: ruff==0.13.2; extra == "linter"
16
- Provides-Extra: dev
17
- Requires-Dist: ruff==0.13.2; extra == "dev"
18
- Requires-Dist: coincurve==13.0.0; extra == "dev"
19
- Requires-Dist: python-dotenv==0.13.0; extra == "dev"
20
- Requires-Dist: twine==6.2.0; extra == "dev"
21
- Requires-Dist: pytest==8.4.2; extra == "dev"
22
- Requires-Dist: mock==5.2.0; extra == "dev"
23
- Dynamic: author
24
- Dynamic: author-email
25
- Dynamic: home-page
26
- Dynamic: license-file
27
- Dynamic: provides-extra
28
- Dynamic: requires-dist
29
- Dynamic: requires-python
30
- Dynamic: summary
@@ -1,15 +0,0 @@
1
- web3<8.0.0,>=6.20.2
2
- pyzmq==27.1.0
3
- pem==23.1.0
4
- cryptography<47.0.0,>=46.0.1
5
-
6
- [dev]
7
- ruff==0.13.2
8
- coincurve==13.0.0
9
- python-dotenv==0.13.0
10
- twine==6.2.0
11
- pytest==8.4.2
12
- mock==5.2.0
13
-
14
- [linter]
15
- ruff==0.13.2
File without changes
File without changes
File without changes
File without changes