safeheron-api-sdk-python 1.1.13__tar.gz → 1.1.15__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.
Files changed (22) hide show
  1. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/PKG-INFO +1 -1
  2. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/account_api.py +15 -4
  3. safeheron_api_sdk_python-1.1.15/safeheron_api_sdk_python/api/tools_api.py +32 -0
  4. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/web3_api.py +10 -5
  5. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/cosigner/co_signer_converter.py +66 -11
  6. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/tools.py +21 -0
  7. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python.egg-info/PKG-INFO +1 -1
  8. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python.egg-info/SOURCES.txt +1 -0
  9. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/setup.py +1 -1
  10. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/LICENSE +0 -0
  11. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/README.rst +0 -0
  12. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/coin_api.py +0 -0
  13. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/mpc_sign_api.py +0 -0
  14. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/transaction_api.py +0 -0
  15. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/webhook_api.py +0 -0
  16. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/api/whitelist_api.py +0 -0
  17. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/client.py +0 -0
  18. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python/webhook/webhook_converter.py +0 -0
  19. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python.egg-info/dependency_links.txt +0 -0
  20. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python.egg-info/requires.txt +0 -0
  21. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/safeheron_api_sdk_python.egg-info/top_level.txt +0 -0
  22. {safeheron_api_sdk_python-1.1.13 → safeheron_api_sdk_python-1.1.15}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: safeheron_api_sdk_python
3
- Version: 1.1.13
3
+ Version: 1.1.15
4
4
  Summary: Python for Safeheron API
5
5
  Home-page: https://github.com/Safeheron/safeheron-api-sdk-python
6
6
  Author: safeheron
@@ -31,7 +31,7 @@ class OneAccountRequest:
31
31
 
32
32
  class CreateAccountRequest:
33
33
  def __init__(self):
34
- # Account name, within 30 characters
34
+ # Account name, 50 characters max
35
35
  self.accountName = None
36
36
  # Merchant unique business ID (100 characters max)
37
37
  # The customerRefId uniquely represents a wallet. In the case of duplicate customerRefId values (for example, when resubmitting due to request timeouts or other errors), the data returned by the interface will remain consistent
@@ -49,7 +49,7 @@ class CreateAccountRequest:
49
49
 
50
50
  class BatchCreateAccountRequest:
51
51
  def __init__(self):
52
- # The prefix of wallet account name, 30 characters max
52
+ # The prefix of wallet account name, 50 characters max
53
53
  self.accountName = None
54
54
  # Display status in Safeheron App
55
55
  # True: not display
@@ -132,6 +132,11 @@ class InfoAccountCoinAddressRequest:
132
132
  # Coin receiving address
133
133
  self.address = None
134
134
 
135
+ class AccountCoinBalanceRequest:
136
+ def __init__(self):
137
+ # Coin Keys, max 10
138
+ self.coinKeyList = None
139
+
135
140
 
136
141
  class RenameAccountCoinAddressRequest:
137
142
  def __init__(self):
@@ -160,9 +165,9 @@ class BatchCreateAccountCoinUTXORequest:
160
165
  self.coinKey = None
161
166
  # Account key
162
167
  self.accountKey = None
163
- # Address group name, 30 characters max
164
- self.count = None
165
168
  # The number, max is 100
169
+ self.count = None
170
+ # Address group name, 30 characters max
166
171
  self.addressGroupName = None
167
172
 
168
173
 
@@ -240,6 +245,12 @@ class AccountApi:
240
245
  def info_account_coin_address(self, request: InfoAccountCoinAddressRequest):
241
246
  return self.api_client.send_request(request, '/v1/account/coin/address/info')
242
247
 
248
+ # Retrieve Coin Balance
249
+ # Get the coin balance of all asset wallets under the team.
250
+ def account_coin_balance(self, request: AccountCoinBalanceRequest):
251
+ return self.api_client.send_request(request, '/v1/account/coin/balance')
252
+
253
+
243
254
  # Rename Coin Address Group of a Wallet Account
244
255
  # Rename a coin address group of a wallet account.
245
256
  def rename_account_coin_address(self, request: RenameAccountCoinAddressRequest):
@@ -0,0 +1,32 @@
1
+ from safeheron_api_sdk_python.client import *
2
+
3
+
4
+ class AmlCheckerRequestRequest:
5
+ def __init__(self):
6
+ # Blockchain network, supports:
7
+ # Bitcoin
8
+ # Ethereum
9
+ # Tron
10
+ self.network = None
11
+ # Address
12
+ self.address = None
13
+
14
+
15
+ class AmlCheckerRetrievesRequest:
16
+ def __init__(self):
17
+ # Risk assessment request ID, which can be created through the Create AML Risk Assessment Request interface.
18
+ self.requestId = None
19
+
20
+
21
+ class ToolsApi:
22
+
23
+ def __init__(self, config):
24
+ self.api_client = Client(config)
25
+
26
+ # Create AML Risk Assessment Request
27
+ def aml_checker_request(self, request: AmlCheckerRequestRequest):
28
+ return self.api_client.send_request(request, '/v1/tools/aml-checker/request')
29
+
30
+ # Retrieve AML Risk Assessment Result
31
+ def aml_checker_retrieves(self, request: AmlCheckerRetrievesRequest):
32
+ return self.api_client.send_request(request, '/v1/tools/aml-checker/retrieves')
@@ -3,7 +3,7 @@ from safeheron_api_sdk_python.client import *
3
3
 
4
4
  class CreateWeb3AccountRequest:
5
5
  def __init__(self):
6
- # Account name, within 30 characters
6
+ # Account name, 50 characters max
7
7
  self.accountName = None
8
8
  # Whether display in Safeheron Console
9
9
  # True: not display
@@ -17,10 +17,15 @@ class CreateWeb3AccountRequest:
17
17
 
18
18
  class BatchCreateWeb3AccountRequest:
19
19
  def __init__(self):
20
- # Transaction key
21
- self.txKey = None
22
- # Merchant unique business ID (100 characters max)
23
- self.customerRefId = None
20
+ # The prefix of wallet account name, 50 characters max
21
+ self.accountName = None
22
+ # Whether display in Safeheron Console
23
+ # True: not display
24
+ # False: display
25
+ # Default: false
26
+ self.hiddenOnUI = None
27
+ # Number of wallets to be created, greater than 0, less than 100
28
+ self.count = None
24
29
 
25
30
 
26
31
  class ListWeb3AccountRequest:
@@ -9,18 +9,33 @@ class CoSignerResponse:
9
9
  self.txKey = None
10
10
 
11
11
 
12
+ class CoSignerResponseV3:
13
+ def __init__(self):
14
+ # action
15
+ self.action = None
16
+ # approvalId
17
+ self.approvalId = None
18
+
19
+
12
20
  class CoSignerConverter:
13
21
 
14
22
  def __init__(self, config):
15
- self.api_pub_key = config['apiPubKey']
16
- if config.get('bizPrivKey'):
17
- self.biz_privKey = PEM_PRIVATE_HEAD + config['bizPrivKey'] + PEM_PRIVATE_END
18
- if config.get('bizPrivKeyPemFile'):
19
- self.biz_privKey = load_rsa_private_key(config['bizPrivKeyPemFile'])
23
+ # Supports both coSignerPubKey and apiPublKey
24
+ self.co_signer_pub_key = config.get('coSignerPubKey') or config.get('apiPubKey')
25
+
26
+ # Supports both approvalCallbackServicePrivateKey and bizPrivKey
27
+ private_key = config.get('approvalCallbackServicePrivateKey') or config.get('bizPrivKey')
28
+ if private_key:
29
+ self.approval_callback_service_private_key = PEM_PRIVATE_HEAD + private_key + PEM_PRIVATE_END
30
+
31
+ # Supports both approvalCallbackServicePrivateKeyPemFile and bizPrivKeyPemFile
32
+ pem_file = config.get('approvalCallbackServicePrivateKeyPemFile') or config.get('bizPrivKeyPemFile')
33
+ if pem_file:
34
+ self.approval_callback_service_private_key = load_rsa_private_key(pem_file)
20
35
 
21
36
  def request_convert(self, co_signer_call_back):
22
- platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.api_pub_key + PEM_PUBLIC_END)
23
- api_user_rsa_sk = get_rsa_key(self.biz_privKey)
37
+ platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.co_signer_pub_key + PEM_PUBLIC_END)
38
+ api_user_rsa_sk = get_rsa_key(self.approval_callback_service_private_key)
24
39
  required_keys = {
25
40
  'key',
26
41
  'sig',
@@ -65,10 +80,50 @@ class CoSignerConverter:
65
80
 
66
81
  return json.loads(r.decode())
67
82
 
83
+ def request_v3_convert(self, co_signer_call_back):
84
+ platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.co_signer_pub_key + PEM_PUBLIC_END)
85
+ required_keys = {
86
+ 'version',
87
+ 'sig',
88
+ 'bizContent',
89
+ 'timestamp',
90
+ }
91
+
92
+ missing_keys = required_keys.difference(co_signer_call_back.keys())
93
+ if missing_keys:
94
+ raise Exception(co_signer_call_back)
95
+ co_signer_call_back['version'] = 'v3'
96
+ sig = co_signer_call_back.pop('sig')
97
+
98
+ need_sign_message = sort_request(co_signer_call_back)
99
+ v = rsa_pass_verify(platform_rsa_pk, need_sign_message, sig)
100
+ if not v:
101
+ raise Exception("rsa verify: false")
102
+ return json.loads(b64decode(co_signer_call_back['bizContent']).decode())
103
+
104
+ def response_v3_converter(self, co_signer_response: CoSignerResponseV3):
105
+ api_user_rsa_sk = get_rsa_key(self.approval_callback_service_private_key)
106
+ ret = dict()
107
+ response_data = json.dumps(co_signer_response.__dict__).replace('\'', '\"').replace('\n', '').encode('utf-8')
108
+
109
+ if response_data is not None:
110
+ ret['bizContent'] = b64encode(response_data).decode()
111
+
112
+ ret['timestamp'] = str(int(time.time() * 1000))
113
+ ret['code'] = str('200')
114
+ ret['version'] = str('v3')
115
+ ret['message'] = str('SUCCESS')
116
+
117
+ # 4 sign request
118
+ need_sign_message = sort_request(ret)
119
+ ret['sig'] = rsa_pss_sign(api_user_rsa_sk, need_sign_message)
120
+ return ret
121
+
122
+
68
123
  # It has been Deprecated,Please use convertCoSignerResponseWithNewCryptoType
69
124
  def response_converter(self, co_signer_response: CoSignerResponse):
70
- platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.api_pub_key + PEM_PUBLIC_END)
71
- api_user_rsa_sk = get_rsa_key(self.biz_privKey)
125
+ platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.co_signer_pub_key + PEM_PUBLIC_END)
126
+ api_user_rsa_sk = get_rsa_key(self.approval_callback_service_private_key)
72
127
 
73
128
  ret = dict()
74
129
 
@@ -98,8 +153,8 @@ class CoSignerConverter:
98
153
  return ret
99
154
 
100
155
  def response_converter_with_new_crypto_type(self, co_signer_response: CoSignerResponse):
101
- platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.api_pub_key + PEM_PUBLIC_END)
102
- api_user_rsa_sk = get_rsa_key(self.biz_privKey)
156
+ platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + self.co_signer_pub_key + PEM_PUBLIC_END)
157
+ api_user_rsa_sk = get_rsa_key(self.approval_callback_service_private_key)
103
158
 
104
159
  ret = dict()
105
160
 
@@ -8,6 +8,7 @@ from Cryptodome.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
8
8
  from Cryptodome.Hash import SHA256, SHA1
9
9
  from Cryptodome import Random
10
10
  from Crypto.Cipher import PKCS1_OAEP
11
+ from Cryptodome.Signature import pss
11
12
  import json
12
13
  import time
13
14
  import requests
@@ -147,6 +148,16 @@ def rsa_sign(private_key, message_hash: bytes):
147
148
  except Exception as e:
148
149
  raise Exception("rsa sign error: %s" % e)
149
150
 
151
+ def rsa_pss_sign(private_key, message_hash: bytes):
152
+ try:
153
+ signer = pss.new(private_key)
154
+ digest = SHA256.new()
155
+ digest.update(message_hash)
156
+ signed = signer.sign(digest)
157
+ return b64encode(signed).decode()
158
+ except Exception as e:
159
+ raise Exception("rsa sign error: %s" % e)
160
+
150
161
 
151
162
  def rsa_verify(public_key, message_hash: bytes, signature):
152
163
  try:
@@ -157,6 +168,16 @@ def rsa_verify(public_key, message_hash: bytes, signature):
157
168
  except Exception as e:
158
169
  raise Exception("rsa sign error: %s" % e)
159
170
 
171
+ def rsa_pass_verify(public_key, message_hash: bytes, signature):
172
+ try:
173
+ verifier = pss.new(public_key)
174
+ digest = SHA256.new()
175
+ digest.update(message_hash)
176
+ verifier.verify(digest, b64decode(signature))
177
+ return True
178
+ except Exception as e:
179
+ raise Exception("rsa sign error: %s" % e)
180
+
160
181
 
161
182
  def sort_request(r: dict):
162
183
  sortData = json.dumps(r, sort_keys=True).replace(' ', '')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: safeheron_api_sdk_python
3
- Version: 1.1.13
3
+ Version: 1.1.15
4
4
  Summary: Python for Safeheron API
5
5
  Home-page: https://github.com/Safeheron/safeheron-api-sdk-python
6
6
  Author: safeheron
@@ -11,6 +11,7 @@ safeheron_api_sdk_python.egg-info/top_level.txt
11
11
  safeheron_api_sdk_python/api/account_api.py
12
12
  safeheron_api_sdk_python/api/coin_api.py
13
13
  safeheron_api_sdk_python/api/mpc_sign_api.py
14
+ safeheron_api_sdk_python/api/tools_api.py
14
15
  safeheron_api_sdk_python/api/transaction_api.py
15
16
  safeheron_api_sdk_python/api/web3_api.py
16
17
  safeheron_api_sdk_python/api/webhook_api.py
@@ -3,7 +3,7 @@ from setuptools import find_packages
3
3
  with open("README.rst", "r") as f:
4
4
  long_description = f.read()
5
5
  setup(name='safeheron_api_sdk_python',
6
- version='1.1.13',
6
+ version='1.1.15',
7
7
  description='Python for Safeheron API',
8
8
  long_description=long_description,
9
9
  author='safeheron',