safeheron-api-sdk-python 1.0.5__tar.gz → 1.0.7__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.
- {safeheron_api_sdk_python-1.0.5/safeheron_api_sdk_python.egg-info → safeheron_api_sdk_python-1.0.7}/PKG-INFO +6 -1
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/api/account_api.py +219 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/api/coin_api.py +69 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/api/mpc_sign_api.py +77 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/api/transaction_api.py +298 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/api/web3_api.py +257 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/cosigner/co_signer_converter.py +90 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python/webhook/webhook_converter.py +51 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python.egg-info}/PKG-INFO +6 -1
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python.egg-info/SOURCES.txt +18 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python.egg-info/requires.txt +5 -0
- safeheron_api_sdk_python-1.0.7/safeheron_api_sdk_python.egg-info/top_level.txt +1 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/setup.py +14 -3
- safeheron_api_sdk_python-1.0.5/safeheron_api_sdk_python.egg-info/SOURCES.txt +0 -10
- safeheron_api_sdk_python-1.0.5/safeheron_api_sdk_python.egg-info/top_level.txt +0 -1
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/LICENSE +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/README.md +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/README.rst +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/safeheron_api_sdk_python/client.py +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/safeheron_api_sdk_python/tools.py +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/safeheron_api_sdk_python.egg-info/dependency_links.txt +0 -0
- {safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: safeheron_api_sdk_python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.7
|
|
4
4
|
Summary: Python for Safeheron API
|
|
5
5
|
Home-page: https://github.com/Safeheron/safeheron-api-sdk-python
|
|
6
6
|
Author: safeheron
|
|
@@ -10,5 +10,10 @@ Platform: all
|
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
License-File: LICENSE
|
|
13
|
+
Requires-Dist: Cryptodome
|
|
14
|
+
Requires-Dist: base64
|
|
15
|
+
Requires-Dist: json
|
|
16
|
+
Requires-Dist: time
|
|
17
|
+
Requires-Dist: cryptography
|
|
13
18
|
|
|
14
19
|
# Python SDK for Safeheron API
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.client import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ListAccountRequest:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# Page number, start from 1 (default)
|
|
10
|
+
self.pageNumber = None
|
|
11
|
+
# The number of bars per page, the default is 10, max is 100
|
|
12
|
+
self.pageSize = None
|
|
13
|
+
# Filter whether there are not-displayed wallet accounts in Safeheron Console
|
|
14
|
+
# True: retrieve hidden wallet accounts
|
|
15
|
+
# False: retrieve displayed wallet accounts
|
|
16
|
+
# Default: retrieve all wallet accounts
|
|
17
|
+
self.hiddenOnUI = None
|
|
18
|
+
# Filter the response based on this account name prefix
|
|
19
|
+
self.namePrefix = None
|
|
20
|
+
# Filter the response based on this account name suffix
|
|
21
|
+
self.nameSuffix = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CreateAccountRequest:
|
|
25
|
+
def __init__(self):
|
|
26
|
+
# Account name, within 30 characters
|
|
27
|
+
self.accountName = None
|
|
28
|
+
# Whether display in Safeheron Console
|
|
29
|
+
# True: not display
|
|
30
|
+
# False: display
|
|
31
|
+
# Default: false
|
|
32
|
+
self.hiddenOnUI = None
|
|
33
|
+
# Account tag
|
|
34
|
+
self.accountTag = None
|
|
35
|
+
# Coin key list, 20 array elements max
|
|
36
|
+
self.coinKeyList = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BatchCreateAccountRequest:
|
|
40
|
+
def __init__(self):
|
|
41
|
+
# The prefix of wallet account name, 30 characters max
|
|
42
|
+
self.accountName = None
|
|
43
|
+
# Number of wallets to be created, greater than 0, less than 100
|
|
44
|
+
self.count = None
|
|
45
|
+
# Account tag
|
|
46
|
+
self.accountTag = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class UpdateAccountShowStateRequest:
|
|
50
|
+
def __init__(self):
|
|
51
|
+
# Wallet account key
|
|
52
|
+
self.accountKey = None
|
|
53
|
+
# Whether display in Safeheron Console
|
|
54
|
+
# True: not display
|
|
55
|
+
# False: display
|
|
56
|
+
# Default: false
|
|
57
|
+
self.hiddenOnUI = None
|
|
58
|
+
|
|
59
|
+
class BatchUpdateAccountTagRequest:
|
|
60
|
+
def __init__(self):
|
|
61
|
+
# Wallet account key
|
|
62
|
+
self.accountKey = None
|
|
63
|
+
# Account tag
|
|
64
|
+
self.accountTag = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CreateAccountCoinRequest:
|
|
68
|
+
def __init__(self):
|
|
69
|
+
# Coin key
|
|
70
|
+
self.coinKey = None
|
|
71
|
+
# Account key
|
|
72
|
+
self.accountKey = None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class BatchCreateAccountCoinRequest:
|
|
76
|
+
def __init__(self):
|
|
77
|
+
# Coin key
|
|
78
|
+
self.coinKey = None
|
|
79
|
+
# Account key, max is 100
|
|
80
|
+
self.accountKeyList = None
|
|
81
|
+
# Address group name, 30 characters max
|
|
82
|
+
self.addressGroupName = None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ListAccountCoinRequest:
|
|
86
|
+
def __init__(self):
|
|
87
|
+
# Account key
|
|
88
|
+
self.accountKey = None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class ListAccountCoinAddressRequest:
|
|
92
|
+
def __init__(self):
|
|
93
|
+
# Page number, start from 1 (default)
|
|
94
|
+
self.pageNumber = None
|
|
95
|
+
# The number of bars per page, the default is 10, max is 100
|
|
96
|
+
self.pageSize = None
|
|
97
|
+
# Coin key
|
|
98
|
+
self.coinKey = None
|
|
99
|
+
# Account key
|
|
100
|
+
self.accountKey = None
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class InfoAccountCoinAddressRequest:
|
|
104
|
+
def __init__(self):
|
|
105
|
+
# Coin key
|
|
106
|
+
self.coinKey = None
|
|
107
|
+
# Coin receiving address
|
|
108
|
+
self.address = None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class RenameAccountCoinAddressRequest:
|
|
112
|
+
def __init__(self):
|
|
113
|
+
# Address group key
|
|
114
|
+
self.addressGroupKey = None
|
|
115
|
+
# Address group name, 30 characters max
|
|
116
|
+
self.addressGroupName = None
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class CreateAccountCoinAddressRequest:
|
|
120
|
+
def __init__(self):
|
|
121
|
+
# Coin key
|
|
122
|
+
self.coinKey = None
|
|
123
|
+
# Account key
|
|
124
|
+
self.accountKey = None
|
|
125
|
+
# Address group name, 30 characters max
|
|
126
|
+
self.addressGroupName = None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class BatchCreateAccountCoinUTXORequest:
|
|
130
|
+
def __init__(self):
|
|
131
|
+
# Coin key
|
|
132
|
+
self.coinKey = None
|
|
133
|
+
# Account key
|
|
134
|
+
self.accountKey = None
|
|
135
|
+
# Address group name, 30 characters max
|
|
136
|
+
self.count = None
|
|
137
|
+
# The number, max is 100
|
|
138
|
+
self.addressGroupName = None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class AccountApi:
|
|
142
|
+
|
|
143
|
+
def __init__(self, config):
|
|
144
|
+
global api_client
|
|
145
|
+
api_client = Client(config)
|
|
146
|
+
|
|
147
|
+
# List Wallet Accounts
|
|
148
|
+
# Filter wallet account lists in team according to different combinations of conditions.
|
|
149
|
+
def list_accounts(self, request: ListAccountRequest):
|
|
150
|
+
return api_client.send_request(request, '/v1/account/list')
|
|
151
|
+
|
|
152
|
+
# Create a new wallet account.
|
|
153
|
+
def create_account(self, request: CreateAccountRequest):
|
|
154
|
+
return api_client.send_request(request, '/v1/account/create')
|
|
155
|
+
|
|
156
|
+
# Batch Create Wallet Accounts V1
|
|
157
|
+
# Generate a batch of wallet accounts based on a specified quantity. By default, the wallet accounts created in bulk will not be displayed in the Safeheron App. For optimal results, we recommend using the V2 version.
|
|
158
|
+
def batchCreate_accountV1(self, request: BatchCreateAccountRequest):
|
|
159
|
+
return api_client.send_request(request, '/v1/account/batch/create')
|
|
160
|
+
|
|
161
|
+
# Batch Create Wallet Accounts V2
|
|
162
|
+
# Generate a batch of wallet accounts based on a specified quantity. By default, the wallet accounts created in bulk will not be displayed in the Safeheron App.
|
|
163
|
+
def batch_create_accountV2(self, request: BatchCreateAccountRequest):
|
|
164
|
+
return api_client.send_request(request, '/v2/account/batch/create')
|
|
165
|
+
|
|
166
|
+
# Change Display of Wallet Account in App
|
|
167
|
+
# Change wallet account status in Safeheron App.
|
|
168
|
+
def update_account_show_state(self, request: UpdateAccountShowStateRequest):
|
|
169
|
+
return api_client.send_request(request, '/v1/account/update/show/state')
|
|
170
|
+
|
|
171
|
+
# Batch Label Wallet Accounts
|
|
172
|
+
# Relabel a batch of wallet accounts.
|
|
173
|
+
# Please note that it only supports to label wallets which are created by API. And, the wallets have been used to sweep the target account cannot be relabelled.
|
|
174
|
+
def batch_update_account_tag(self, request: BatchUpdateAccountTagRequest):
|
|
175
|
+
return api_client.send_request(request, '/v1/account/batch/update/tag')
|
|
176
|
+
|
|
177
|
+
# Add Coins to a Wallet Account
|
|
178
|
+
# Add a new coin to your wallet account, while generating the default address group for the added coin. Once successfully completed, it will return the address information of the newly created default address group. In case the added currency already exists within the account, it will promptly return the existing default address group information for that coin.
|
|
179
|
+
# In a wallet account, UTXO-based cryptocurrencies can have multiple address groups, while other types of cryptocurrencies usually have only one. To check whether a particular cryptocurrency supports the addition of multiple address groups, simply check the 'isMultipleAddress' parameter through the Coin List.
|
|
180
|
+
def create_account_coin(self, request: CreateAccountCoinRequest):
|
|
181
|
+
return api_client.send_request(request, '/v1/account/coin/create')
|
|
182
|
+
|
|
183
|
+
# Batch Add Coins to Wallet Accounts
|
|
184
|
+
# Bulk addition of specified coins to designated wallet accounts. And, it creates a default address group for each coin and returns the address information contained within the newly created default address group. If a wallet account already contains the currency being added, the function will return the default address group data for that existing coin.
|
|
185
|
+
#
|
|
186
|
+
def batch_create_account_coin(self, request: BatchCreateAccountCoinRequest):
|
|
187
|
+
return api_client.send_request(request, '/v1/account/batch/coin/create')
|
|
188
|
+
|
|
189
|
+
# List Coins Within a Wallet Account
|
|
190
|
+
# Retrieve a complete list of all coins associated with a wallet account, along with the default address group information for each coin.
|
|
191
|
+
#
|
|
192
|
+
def list_account_coin(self, request: ListAccountCoinRequest):
|
|
193
|
+
return api_client.send_request(request, '/v1/account/coin/list')
|
|
194
|
+
|
|
195
|
+
# List Coin Address Group of a Wallet Account
|
|
196
|
+
# Retrieve all address groups for a coin within the wallet account.
|
|
197
|
+
#
|
|
198
|
+
def list_account_coin_address(self, request: ListAccountCoinAddressRequest):
|
|
199
|
+
return api_client.send_request(request, '/v1/account/coin/address/list')
|
|
200
|
+
|
|
201
|
+
# Retrieve The Balance of an Address
|
|
202
|
+
# Retrieve the balance of a specific coin address.
|
|
203
|
+
def info_account_coin_address(self, request: InfoAccountCoinAddressRequest):
|
|
204
|
+
return api_client.send_request(request, '/v1/account/coin/address/info')
|
|
205
|
+
|
|
206
|
+
# Rename Coin Address Group of a Wallet Account
|
|
207
|
+
# Rename a coin address group of a wallet account.
|
|
208
|
+
def rename_account_coin_address(self, request: RenameAccountCoinAddressRequest):
|
|
209
|
+
return api_client.send_request(request, '/v1/account/coin/address/name')
|
|
210
|
+
|
|
211
|
+
# Add Address Group for UTXO-Based Coin
|
|
212
|
+
# Add a new address group for UTXO-based cryptocurrencies under a wallet account. If the coin does not exist, it will be added first, followed by the new address group. The function will return the details of the added address(es).
|
|
213
|
+
def create_account_coin_address(self, request: CreateAccountCoinAddressRequest):
|
|
214
|
+
return api_client.send_request(request, '/v1/account/coin/address/create')
|
|
215
|
+
|
|
216
|
+
# Batch Add Address Groups for UTXO-Based Coin
|
|
217
|
+
# For UTXO-based coins in a wallet account, it is possible to add multiple address groups to the account in bulk by specifying the wallet account and the desired number of address groups. The function will return the details of the added address groups. If the specified coin does not exist in the account, it will be added first, followed by the addition of the corresponding number of address groups.
|
|
218
|
+
def batch_create_account_coin_UTXO(self, request: BatchCreateAccountCoinUTXORequest):
|
|
219
|
+
return api_client.send_request(request, '/v1/account/coin/utxo/batch/create')
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.client import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CheckCoinAddressRequest:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# Coin key
|
|
10
|
+
self.coinKey = None
|
|
11
|
+
# Coin receiving address
|
|
12
|
+
self.address = None
|
|
13
|
+
# Verify contract address (If no value is provided, 'false' by default)
|
|
14
|
+
# True: verify
|
|
15
|
+
# False: not verify
|
|
16
|
+
self.checkContract = None
|
|
17
|
+
# Verify AML compliance (If no value is provided or be verified, AML-compliant address by default)
|
|
18
|
+
# True: verify
|
|
19
|
+
# False: not verify
|
|
20
|
+
self.checkAml = None
|
|
21
|
+
# Verify the validity of address format (If no value is provided, 'false' by dafault)
|
|
22
|
+
# True: verify
|
|
23
|
+
# False: not verify
|
|
24
|
+
self.checkAddressValid = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CoinBalanceSnapshotRequest:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
# Only supports querying data within the last 30 days, with the parameter a GMT+8 time in the format of yyyy-MM-dd provided.
|
|
30
|
+
# Note: If the provided value is the current date (not a historical date), it will return the balance up to the current time.
|
|
31
|
+
self.gmt8Date = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CoinBlockHeightRequest:
|
|
35
|
+
def __init__(self):
|
|
36
|
+
# Coin key, multiple coin keys are separated by commas
|
|
37
|
+
self.coinKey = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CoinApi:
|
|
41
|
+
|
|
42
|
+
def __init__(self, config):
|
|
43
|
+
global api_client
|
|
44
|
+
api_client = Client(config)
|
|
45
|
+
|
|
46
|
+
# Coin List
|
|
47
|
+
# Retrieve the list of coins supported by Safeheron.
|
|
48
|
+
def list_coin(self):
|
|
49
|
+
return api_client.send_request(None, '/v1/coin/list')
|
|
50
|
+
|
|
51
|
+
# Coin Maintenance List
|
|
52
|
+
# Retrieve the information of coins under maintenance in Safeheron.
|
|
53
|
+
def list_coin_maintain(self):
|
|
54
|
+
return api_client.send_request(None, '/v1/coin/maintain/list')
|
|
55
|
+
|
|
56
|
+
# Verify Coin Address
|
|
57
|
+
# Verify the correctness of a cryptocurrency address based on the provided validation attributes.
|
|
58
|
+
def check_coin_address(self, request: CheckCoinAddressRequest):
|
|
59
|
+
return api_client.send_request(request, '/v1/coin/address/check')
|
|
60
|
+
|
|
61
|
+
# Snapshot the Coin Balance
|
|
62
|
+
# Safeheron takes and stores daily snapshots of balances based on the transaction block's creation time in GMT+8. Please note that the snapshot only keeps data within 30 days.
|
|
63
|
+
def coin_balance_snapshot(self, request: CoinBalanceSnapshotRequest):
|
|
64
|
+
return api_client.send_request(request, '/v1/coin/balance/snapshot')
|
|
65
|
+
|
|
66
|
+
# Retrieve Current Block Height for Currency
|
|
67
|
+
# Retrieve the current block height for a specific cryptocurrency by providing its key.
|
|
68
|
+
def coin_block_height(self, request: CoinBlockHeightRequest):
|
|
69
|
+
return api_client.send_request(request, '/v1/coin/block/height')
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.client import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CreateMPCSignTransactionRequest:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# Merchant unique business ID (100 characters max)
|
|
10
|
+
self.customerRefId = None
|
|
11
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
12
|
+
self.customerExt1 = None
|
|
13
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
14
|
+
self.customerExt2 = None
|
|
15
|
+
# Source account key
|
|
16
|
+
self.sourceAccountKey = None
|
|
17
|
+
# Signature algorithm
|
|
18
|
+
self.signAlg = None
|
|
19
|
+
# Transaction fee rate, either txFeeLevel or feeRateDto
|
|
20
|
+
self.dataList = [self.Date()]
|
|
21
|
+
|
|
22
|
+
def asDict(self):
|
|
23
|
+
dict = self.__dict__
|
|
24
|
+
dict["dataList"] = [data.__dict__ for data in dict["dataList"]]
|
|
25
|
+
return dict
|
|
26
|
+
|
|
27
|
+
class Date:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
# Transaction note (180 characters max)
|
|
30
|
+
self.note = None
|
|
31
|
+
# Transaction data to be signed (view description below for details)
|
|
32
|
+
self.data = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class OneMPCSignTransactionsRequest:
|
|
36
|
+
def __init__(self):
|
|
37
|
+
# Transaction key
|
|
38
|
+
self.txKey = None
|
|
39
|
+
# Merchant unique business ID (100 characters max)
|
|
40
|
+
self.customerRefId = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ListMPCSignTransactionsRequest:
|
|
44
|
+
def __init__(self):
|
|
45
|
+
# Query page direction, NEXT by default
|
|
46
|
+
self.direct = None
|
|
47
|
+
# The number of items to retrieve at a time, default max value is 500
|
|
48
|
+
self.limit = None
|
|
49
|
+
# Txkey of the first transaction record. If the first page has no value, provide the txKey of the last transaction record from the previous result
|
|
50
|
+
self.fromId = None
|
|
51
|
+
# Start time for creating a transaction, UNIX timestamp (ms) (If no value is provided, the default value is createTimeMax minus 24 hours)
|
|
52
|
+
self.createTimeMin = None
|
|
53
|
+
# End time for creating a transaction, UNIX timestamp (ms) (If no value is provided, the default value is the current UTC time)
|
|
54
|
+
self.createTimeMax = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class MPCSignApi:
|
|
58
|
+
|
|
59
|
+
def __init__(self, config):
|
|
60
|
+
global api_client
|
|
61
|
+
api_client = Client(config)
|
|
62
|
+
|
|
63
|
+
# Create an MPC Sign Transaction
|
|
64
|
+
# Merchant can initiate MPC Sign via this interface. The merchant must first serialize the transaction data and generate a hash before using this interface to submit the hash and create a transaction. The resulting signature can be retrieved via the MPC Sign transaction interface or webhook. The merchant can proceed with the necessary follow-up processes to obtain the signature according to their specific needs.
|
|
65
|
+
def create_mpc_sign_transactions(self, request: CreateMPCSignTransactionRequest):
|
|
66
|
+
request.asDict()
|
|
67
|
+
return api_client.send_request(request, '/v1/transactions/mpcsign/create')
|
|
68
|
+
|
|
69
|
+
# Retrieve a Single MPC Sign Transaction
|
|
70
|
+
# To query a specific MPC Sign transaction, either customerRefId or txKey must be provided. If both parameters are provided, the query will be based on the txKey parameter.
|
|
71
|
+
def one_mpc_sign_transactions(self, request: OneMPCSignTransactionsRequest):
|
|
72
|
+
return api_client.send_request(request, '/v1/transactions/mpcsign/one')
|
|
73
|
+
|
|
74
|
+
# MPC Sign Transaction List
|
|
75
|
+
# Filter MPC Sign transaction history by various conditions.
|
|
76
|
+
def list_mpc_sign_transactions(self, request: ListMPCSignTransactionsRequest):
|
|
77
|
+
return api_client.send_request(request, '/v1/transactions/mpcsign/list')
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.client import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ListTransactionsV1Request:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# Page number, start from 1 (default)
|
|
10
|
+
self.pageNumber = None
|
|
11
|
+
# The number of bars per page, the default is 10, max is 100
|
|
12
|
+
self.pageSize = None
|
|
13
|
+
# Source account key
|
|
14
|
+
self.sourceAccountKey = None
|
|
15
|
+
# Source account type
|
|
16
|
+
self.sourceAccountType = None
|
|
17
|
+
# Destination account key
|
|
18
|
+
self.destinationAccountKey = None
|
|
19
|
+
# Destination account type
|
|
20
|
+
self.destinationAccountType = None
|
|
21
|
+
# Start time for creating a transaction, UNIX timestamp (ms)
|
|
22
|
+
self.createTimeMin = None
|
|
23
|
+
# End time for creating a transaction, UNIX timestamp (ms)
|
|
24
|
+
self.createTimeMax = None
|
|
25
|
+
# Min transaction amount
|
|
26
|
+
self.txAmountMin = None
|
|
27
|
+
# Max transaction amount
|
|
28
|
+
self.txAmountMax = None
|
|
29
|
+
# Coin key, multiple coin keys are separated by commas
|
|
30
|
+
self.coinKey = None
|
|
31
|
+
# Transaction fee coin key, multiple coin keys are separated by commas
|
|
32
|
+
self.feeCoinKey = None
|
|
33
|
+
# Transaction status
|
|
34
|
+
self.transactionStatus = None
|
|
35
|
+
# Transaction substatus
|
|
36
|
+
self.transactionSubStatus = None
|
|
37
|
+
# Min duration for completing a transaction, UNIX timestamp (ms)
|
|
38
|
+
self.completedTimeMin = None
|
|
39
|
+
# Max duration for completing a transaction, UNIX timestamp (ms)
|
|
40
|
+
self.completedTimeMax = None
|
|
41
|
+
# Merchant unique business ID
|
|
42
|
+
self.customerRefId = None
|
|
43
|
+
# Type of actual destination account
|
|
44
|
+
self.realDestinationAccountType = None
|
|
45
|
+
# Filter out custom transaction amounts, excluding transaction records below a certain amount specified in USD from the query results
|
|
46
|
+
self.hideSmallAmountUsd = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ListTransactionsV2Request:
|
|
50
|
+
def __init__(self):
|
|
51
|
+
# Query page direction, NEXT by default
|
|
52
|
+
self.direct = None
|
|
53
|
+
# The number of items to retrieve at a time, default max value is 500
|
|
54
|
+
self.limit = None
|
|
55
|
+
# Txkey of the first transaction record. If the first page has no value, provide the txKey of the last transaction record from the previous result
|
|
56
|
+
self.fromId = None
|
|
57
|
+
# Source account key
|
|
58
|
+
self.sourceAccountKey = None
|
|
59
|
+
# Source account type
|
|
60
|
+
self.sourceAccountType = None
|
|
61
|
+
# Destination account key
|
|
62
|
+
self.destinationAccountKey = None
|
|
63
|
+
# Destination account type
|
|
64
|
+
self.destinationAccountType = None
|
|
65
|
+
# Start time for creating a transaction, UNIX timestamp (ms)
|
|
66
|
+
self.createTimeMin = None
|
|
67
|
+
# End time for creating a transaction, UNIX timestamp (ms)
|
|
68
|
+
self.createTimeMax = None
|
|
69
|
+
# Min transaction amount
|
|
70
|
+
self.txAmountMin = None
|
|
71
|
+
# Max transaction amount
|
|
72
|
+
self.txAmountMax = None
|
|
73
|
+
# Coin key, multiple coin keys are separated by commas
|
|
74
|
+
self.coinKey = None
|
|
75
|
+
# Transaction fee coin key, multiple coin keys are separated by commas
|
|
76
|
+
self.feeCoinKey = None
|
|
77
|
+
# Transaction status
|
|
78
|
+
self.transactionStatus = None
|
|
79
|
+
# Transaction substatus
|
|
80
|
+
self.transactionSubStatus = None
|
|
81
|
+
# Min duration for completing a transaction, UNIX timestamp (ms)
|
|
82
|
+
self.completedTimeMin = None
|
|
83
|
+
# Max duration for completing a transaction, UNIX timestamp (ms)
|
|
84
|
+
self.completedTimeMax = None
|
|
85
|
+
# Merchant unique business ID
|
|
86
|
+
self.customerRefId = None
|
|
87
|
+
# Type of actual destination account
|
|
88
|
+
self.realDestinationAccountType = None
|
|
89
|
+
# Filter out custom transaction amounts, excluding transaction records below a certain amount specified in USD from the query results
|
|
90
|
+
self.hideSmallAmountUsd = None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class CreateTransactionRequest:
|
|
94
|
+
def __init__(self):
|
|
95
|
+
# Merchant unique business ID (100 characters max)
|
|
96
|
+
self.customerRefId = None
|
|
97
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
98
|
+
self.customerExt1 = None
|
|
99
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
100
|
+
self.customerExt2 = None
|
|
101
|
+
# Transaction note (180 characters max)
|
|
102
|
+
self.note = None
|
|
103
|
+
# Coin key
|
|
104
|
+
self.coinKey = None
|
|
105
|
+
# Transaction Fee Rate Grade
|
|
106
|
+
# Choose between transaction fees. If the transaction fee rate is preset, it will take priority
|
|
107
|
+
self.txFeeLevel = None
|
|
108
|
+
# Transaction fee rate, either txFeeLevel or feeRateDto
|
|
109
|
+
self.feeRateDto = FeeRateDto()
|
|
110
|
+
# Maximum estimated transaction fee rate for a given transaction
|
|
111
|
+
self.maxTxFeeRate = None
|
|
112
|
+
# Transaction amount
|
|
113
|
+
self.txAmount = None
|
|
114
|
+
# Deduct transaction fee from the transfer amount
|
|
115
|
+
# False by default. If set to true, transaction fee will be deducted from the transfer amount
|
|
116
|
+
# Note: This parameter can only be considered if a transaction’s asset is a base asset, such as ETH or MATIC. If the asset can’t be used for transaction fees, like USDC, this parameter is ignored
|
|
117
|
+
self.treatAsGrossAmount = None
|
|
118
|
+
# Source account key
|
|
119
|
+
self.sourceAccountKey = None
|
|
120
|
+
# Account type
|
|
121
|
+
self.sourceAccountType = None
|
|
122
|
+
# Destination account key
|
|
123
|
+
# Whitelist key if the destination is a whitelisted account;
|
|
124
|
+
# Wallet account key if the destination is a wallet account;
|
|
125
|
+
# No key for unknown address
|
|
126
|
+
self.destinationAccountKey = None
|
|
127
|
+
# Destination account type
|
|
128
|
+
self.destinationAccountType = None
|
|
129
|
+
# If the destinationAccountType is ONE_TIME_ADDRESS, then this field should have a value
|
|
130
|
+
self.destinationAddress = None
|
|
131
|
+
# Destination Tag
|
|
132
|
+
self.destinationTag = None
|
|
133
|
+
# Bitcoin enabled for RBF (Replace-by-fee is a protocol in the Bitcoin mempool that allows for the replacement of an unconfirmed transaction with another one)
|
|
134
|
+
self.isRbf = None
|
|
135
|
+
# The default setting for the parameter is [true]. This parameter determines whether a transaction can be created when the target address is a smart contract. If set to [false], a transaction can still be created for a contract address
|
|
136
|
+
self.failOnContract = None
|
|
137
|
+
# Custom nonce
|
|
138
|
+
self.nonce = None
|
|
139
|
+
# Balance verification, BALANCE_CHECK by default
|
|
140
|
+
self.balanceVerifyType = None
|
|
141
|
+
|
|
142
|
+
def asDict(self):
|
|
143
|
+
dict = self.__dict__
|
|
144
|
+
dict["feeRateDto"] = dict["feeRateDto"].__dict__
|
|
145
|
+
return dict
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class FeeRateDto:
|
|
149
|
+
def __init__(self):
|
|
150
|
+
# Fee rate: fee per byte for UTXO, gas price for EVM chains, free limit for TRON (optional) and gas price for SUI
|
|
151
|
+
self.feeRate = None
|
|
152
|
+
# EVM gas limit
|
|
153
|
+
self.gasLimit = None
|
|
154
|
+
# EIP-1559 max priority fee
|
|
155
|
+
self.maxPriorityFee = None
|
|
156
|
+
# EIP-1559 max fee
|
|
157
|
+
self.maxFee = None
|
|
158
|
+
# Filecoin gas premium, similar to EIP-1559 max priority fee
|
|
159
|
+
self.gasPremium = None
|
|
160
|
+
# Filecoin gas fee cap, similar to EIP-1559 max fee
|
|
161
|
+
self.gasFeeCap = None
|
|
162
|
+
# SUI gas budget, similar to EIP-1559 max fee
|
|
163
|
+
self.gasBudget = None
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class RecreateTransactionRequest:
|
|
167
|
+
def __init__(self):
|
|
168
|
+
# Transaction key
|
|
169
|
+
self.txKey = None
|
|
170
|
+
# Transaction hash
|
|
171
|
+
self.txHash = None
|
|
172
|
+
# Coin key
|
|
173
|
+
self.coinKey = None
|
|
174
|
+
# Transaction Fee Rate Grade
|
|
175
|
+
# Choose between transaction fees. If the transaction fee rate is preset, it will take priority
|
|
176
|
+
self.txFeeLevel = None
|
|
177
|
+
# Transaction fee rate, either txFeeLevel or feeRateDto
|
|
178
|
+
self.feeRateDto = FeeRateDto()
|
|
179
|
+
|
|
180
|
+
def asDict(self):
|
|
181
|
+
dict = self.__dict__
|
|
182
|
+
dict["feeRateDto"] = dict["feeRateDto"].__dict__
|
|
183
|
+
return dict
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class OneTransactionsRequest:
|
|
187
|
+
def __init__(self):
|
|
188
|
+
# Transaction key
|
|
189
|
+
self.txKey = None
|
|
190
|
+
# Merchant unique business ID (100 characters max)
|
|
191
|
+
self.customerRefId = None
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class TransactionsFeeRateRequest:
|
|
195
|
+
def __init__(self):
|
|
196
|
+
# Coin key
|
|
197
|
+
self.coinKey = None
|
|
198
|
+
# Transaction hash, pass the original transaction hash when speed up transaction estimation
|
|
199
|
+
self.txHash = None
|
|
200
|
+
# Source account key, required for UTXO-based coins
|
|
201
|
+
self.sourceAccountKey = None
|
|
202
|
+
# Source address are required for TRON when estimating transaction fees. For EVM-based transactions, the source address is required when retrieving the gas limit on the blockchain. Otherwise, a default fixed gas limit value will be returned
|
|
203
|
+
self.sourceAddress = None
|
|
204
|
+
# Destination address is optional for TRON and FIL when estimating transaction fees (although providing it may result in a more accurate fee estimation). For EVM-based transactions, the destination address is required when retrieving the gas limit on the blockchain. Otherwise, a default fixed gas limit value will be returned
|
|
205
|
+
self.destinationAddress = None
|
|
206
|
+
# Transfer amount is required to calculate gas limit more accurately when using EVM chains. When using UTXO, providing the amount can estimate transaction fees more accurately. If no amount is provided, the calculation is based on the maximum UTXO quantity. When using SUI, providing the amount can estimate gas budget more accurately
|
|
207
|
+
self.value = None
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class CancelTransactionRequest:
|
|
211
|
+
def __init__(self):
|
|
212
|
+
# Transaction key
|
|
213
|
+
self.txKey = None
|
|
214
|
+
# Transaction type, TRANSACTION by default
|
|
215
|
+
self.txType = None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class CollectionTransactionsUTXORequest:
|
|
219
|
+
def __init__(self):
|
|
220
|
+
# Merchant unique business ID (100 characters max)
|
|
221
|
+
self.customerRefId = None
|
|
222
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
223
|
+
self.customerExt1 = None
|
|
224
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
225
|
+
self.customerExt2 = None
|
|
226
|
+
# Transaction note (180 characters max)
|
|
227
|
+
self.note = None
|
|
228
|
+
# Coin key
|
|
229
|
+
self.coinKey = None
|
|
230
|
+
# Transaction fee rate, the unit is the feeUnit returned by the coin list
|
|
231
|
+
self.txFeeRate = None
|
|
232
|
+
# Transaction Fee Rate Grade
|
|
233
|
+
# Choose between the transaction fee rate. If the transaction fee rate is preset, it will take priority
|
|
234
|
+
self.txFeeLevel = None
|
|
235
|
+
# Maximum estimated transaction fee rate for a given transaction
|
|
236
|
+
self.maxTxFeeRate = None
|
|
237
|
+
# Minimum sweeping amount
|
|
238
|
+
self.minCollectionAmount = None
|
|
239
|
+
# Source account key
|
|
240
|
+
self.sourceAccountKey = None
|
|
241
|
+
# Account type
|
|
242
|
+
self.sourceAccountType = None
|
|
243
|
+
# Destination account key
|
|
244
|
+
self.destinationAccountKey = None
|
|
245
|
+
# Destination account type
|
|
246
|
+
self.destinationAccountType = None
|
|
247
|
+
# If the destinationAccountType is ONE_TIME_ADDRESS, then this field should have a value
|
|
248
|
+
self.destinationAddress = None
|
|
249
|
+
# Destination Tag
|
|
250
|
+
self.destinationTag = None
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class TransactionApi:
|
|
254
|
+
|
|
255
|
+
def __init__(self, config):
|
|
256
|
+
global api_client
|
|
257
|
+
api_client = Client(config)
|
|
258
|
+
|
|
259
|
+
# Transaction List V1
|
|
260
|
+
# Filter transaction history by various conditions. For optimal results, we recommend using the V2 version.
|
|
261
|
+
def list_transactions_v1(self, request: ListTransactionsV1Request):
|
|
262
|
+
return api_client.send_request(request, '/v1/transactions/list')
|
|
263
|
+
|
|
264
|
+
# Transaction List V2
|
|
265
|
+
# Filter transaction history by various conditions.
|
|
266
|
+
def list_transactions_v2(self, request: ListTransactionsV2Request):
|
|
267
|
+
return api_client.send_request(request, '/v2/transactions/list')
|
|
268
|
+
|
|
269
|
+
# Create a new transaction.
|
|
270
|
+
def create_transactions(self, request: CreateTransactionRequest):
|
|
271
|
+
request.asDict()
|
|
272
|
+
return api_client.send_request(request, '/v2/transactions/create')
|
|
273
|
+
|
|
274
|
+
# Speed up EVM and UTXO-based Transactions
|
|
275
|
+
# Transactions with low transaction fees and those that have been pending for a long time can be sped up. EVM-based and BTC transactions can be sped up through RBF(If 'isRbf' is set to true during transaction creation, the transaction will be accelerated using RBF acceleration. Otherwise, CPFP acceleration will be used.) For other UTXO-based transactions, CPFP will be used.
|
|
276
|
+
def recreate_transactions(self, request: RecreateTransactionRequest):
|
|
277
|
+
request.asDict()
|
|
278
|
+
return api_client.send_request(request, '/v2/transactions/recreate')
|
|
279
|
+
|
|
280
|
+
# Retrieve a Transaction
|
|
281
|
+
# To query a transaction, either customerRefId or txKey are required. If both values are provided, the retrieval will be based on the txKey.
|
|
282
|
+
def one_transactions(self, request: OneTransactionsRequest):
|
|
283
|
+
return api_client.send_request(request, '/v1/transactions/one')
|
|
284
|
+
|
|
285
|
+
# Estimate Transaction Fee
|
|
286
|
+
# This interface provides users with an estimated range of transaction fee rates of a given cryptocurrency when creating or speeding up transactions.
|
|
287
|
+
def transaction_fee_rate(self, request: TransactionsFeeRateRequest):
|
|
288
|
+
return api_client.send_request(request, '/v2/transactions/getFeeRate')
|
|
289
|
+
|
|
290
|
+
# Cancel Transaction
|
|
291
|
+
# Cancel the authorization-pending transaction and the signing-in-progress transaction.
|
|
292
|
+
def cancel_transactions(self, request: CancelTransactionRequest):
|
|
293
|
+
return api_client.send_request(request, '/v1/transactions/cancel')
|
|
294
|
+
|
|
295
|
+
# UTXO-Based Coin Sweeping
|
|
296
|
+
# For multi-address UTXO coins under a wallet account, this interface allows users to collect the balances of certain qualifying addresses into a specified destination address.
|
|
297
|
+
def collectionTransactionsUTXO(self, request: CollectionTransactionsUTXORequest):
|
|
298
|
+
return api_client.send_request(request, '/v1/transactions/utxo/collection')
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.client import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CreateWeb3AccountRequest:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# Account name, within 30 characters
|
|
10
|
+
self.accountName = None
|
|
11
|
+
# Whether display in Safeheron Console
|
|
12
|
+
# True: not display
|
|
13
|
+
# False: display
|
|
14
|
+
# Default: false
|
|
15
|
+
self.hiddenOnUI = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BatchCreateWeb3AccountRequest:
|
|
19
|
+
def __init__(self):
|
|
20
|
+
# Transaction key
|
|
21
|
+
self.txKey = None
|
|
22
|
+
# Merchant unique business ID (100 characters max)
|
|
23
|
+
self.customerRefId = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ListWeb3AccountRequest:
|
|
27
|
+
def __init__(self):
|
|
28
|
+
# Query page direction, NEXT by default
|
|
29
|
+
self.direct = None
|
|
30
|
+
# The number of items to retrieve at a time, default max value is 500
|
|
31
|
+
self.limit = None
|
|
32
|
+
# Txkey of the first transaction record. If the first page has no value, provide the txKey of the last transaction record from the previous result
|
|
33
|
+
self.fromId = None
|
|
34
|
+
# Filter the response based on this account name prefix
|
|
35
|
+
self.namePrefix = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CreateWeb3EthSignRequest:
|
|
39
|
+
def __init__(self):
|
|
40
|
+
# Source account key
|
|
41
|
+
self.accountKey = None
|
|
42
|
+
# Merchant unique business ID (100 characters max)
|
|
43
|
+
self.customerRefId = None
|
|
44
|
+
# Transaction note (180 characters max)
|
|
45
|
+
self.note = None
|
|
46
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
47
|
+
self.customerExt1 = None
|
|
48
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
49
|
+
self.customerExt2 = None
|
|
50
|
+
# Message Hash
|
|
51
|
+
self.messageHash = self.MessageHash()
|
|
52
|
+
|
|
53
|
+
def asDict(self):
|
|
54
|
+
dict = self.__dict__
|
|
55
|
+
dict["messageHash"] = dict["messageHash"].__dict__
|
|
56
|
+
return dict
|
|
57
|
+
|
|
58
|
+
class MessageHash:
|
|
59
|
+
def __init__(self):
|
|
60
|
+
# Chain ID (does not participate in signing, only the hash is used for signing)
|
|
61
|
+
self.chainId = None
|
|
62
|
+
# Pending signature hash, hexadecimal string (currently only supports one input)
|
|
63
|
+
self.hash = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class CreateWeb3PersonalSignRequest:
|
|
67
|
+
def __init__(self):
|
|
68
|
+
# Source account key
|
|
69
|
+
self.accountKey = None
|
|
70
|
+
# Merchant unique business ID (100 characters max)
|
|
71
|
+
self.customerRefId = None
|
|
72
|
+
# Transaction note (180 characters max)
|
|
73
|
+
self.note = None
|
|
74
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
75
|
+
self.customerExt1 = None
|
|
76
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
77
|
+
self.customerExt2 = None
|
|
78
|
+
# Message Hash
|
|
79
|
+
self.message = self.Message()
|
|
80
|
+
|
|
81
|
+
def asDict(self):
|
|
82
|
+
dict = self.__dict__
|
|
83
|
+
dict["message"] = dict["message"].__dict__
|
|
84
|
+
return dict
|
|
85
|
+
|
|
86
|
+
class Message:
|
|
87
|
+
def __init__(self):
|
|
88
|
+
# Chain ID (does not participate in signing, only the hash is used for signing)
|
|
89
|
+
self.chainId = None
|
|
90
|
+
# Data to be signed
|
|
91
|
+
self.data = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class CreateWeb3EthSignTypedDataRequest:
|
|
95
|
+
def __init__(self):
|
|
96
|
+
# Source account key
|
|
97
|
+
self.accountKey = None
|
|
98
|
+
# Merchant unique business ID (100 characters max)
|
|
99
|
+
self.customerRefId = None
|
|
100
|
+
# Transaction note (180 characters max)
|
|
101
|
+
self.note = None
|
|
102
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
103
|
+
self.customerExt1 = None
|
|
104
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
105
|
+
self.customerExt2 = None
|
|
106
|
+
# Message Hash
|
|
107
|
+
self.message = self.Message()
|
|
108
|
+
|
|
109
|
+
def asDict(self):
|
|
110
|
+
dict = self.__dict__
|
|
111
|
+
dict["message"] = dict["message"].__dict__
|
|
112
|
+
return dict
|
|
113
|
+
|
|
114
|
+
class Message:
|
|
115
|
+
def __init__(self):
|
|
116
|
+
# Chain ID (does not participate in signing, only the hash is used for signing)
|
|
117
|
+
self.chainId = None
|
|
118
|
+
# Data to be signed
|
|
119
|
+
self.data = None
|
|
120
|
+
# EthSignTypedData Version
|
|
121
|
+
self.version = None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class CreateWeb3EthSignTransactionRequest:
|
|
125
|
+
def __init__(self):
|
|
126
|
+
# Source account key
|
|
127
|
+
self.accountKey = None
|
|
128
|
+
# Merchant unique business ID (100 characters max)
|
|
129
|
+
self.customerRefId = None
|
|
130
|
+
# Transaction note (180 characters max)
|
|
131
|
+
self.note = None
|
|
132
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
133
|
+
self.customerExt1 = None
|
|
134
|
+
# Merchant extended field (defined by merchant) shown to merchant (255 characters max)
|
|
135
|
+
self.customerExt2 = None
|
|
136
|
+
# Transaction
|
|
137
|
+
self.transaction = self.Transaction()
|
|
138
|
+
|
|
139
|
+
def asDict(self):
|
|
140
|
+
dict = self.__dict__
|
|
141
|
+
dict["transaction"] = dict["transaction"].__dict__
|
|
142
|
+
return dict
|
|
143
|
+
|
|
144
|
+
class Transaction:
|
|
145
|
+
def __init__(self):
|
|
146
|
+
# To
|
|
147
|
+
self.to = None
|
|
148
|
+
# Value (Unit: wei)
|
|
149
|
+
self.value = None
|
|
150
|
+
# Chain ID
|
|
151
|
+
self.chainId = None
|
|
152
|
+
# Gas price
|
|
153
|
+
self.gasPrice = None
|
|
154
|
+
# Gas limit
|
|
155
|
+
self.gasLimit = None
|
|
156
|
+
# Max priority fee per gas for EIP-1559
|
|
157
|
+
self.maxPriorityFeePerGas = None
|
|
158
|
+
# Max fee per gas for EIP-1559
|
|
159
|
+
self.maxFeePerGas = None
|
|
160
|
+
# Nonce
|
|
161
|
+
self.nonce = None
|
|
162
|
+
# Data
|
|
163
|
+
self.data = None
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class CancelWeb3SignRequest:
|
|
167
|
+
def __init__(self):
|
|
168
|
+
# Transaction key
|
|
169
|
+
self.txKey = None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class OneWeb3SignRequest:
|
|
173
|
+
def __init__(self):
|
|
174
|
+
# Transaction key
|
|
175
|
+
self.txKey = None
|
|
176
|
+
# Merchant unique business ID (100 characters max)
|
|
177
|
+
self.customerRefId = None
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class ListWeb3SignRequest:
|
|
181
|
+
def __init__(self):
|
|
182
|
+
# Query page direction, NEXT by default
|
|
183
|
+
self.direct = None
|
|
184
|
+
# The number of items to retrieve at a time, default max value is 500
|
|
185
|
+
self.limit = None
|
|
186
|
+
# Txkey of the first transaction record. If the first page has no value, provide the txKey of the last transaction record from the previous result
|
|
187
|
+
self.fromId = None
|
|
188
|
+
# Web3 Sign type
|
|
189
|
+
self.subjectType = None
|
|
190
|
+
# Transaction status
|
|
191
|
+
self.transactionStatus = None
|
|
192
|
+
# Source account key
|
|
193
|
+
self.accountKey = None
|
|
194
|
+
# Start time for creating a transaction, UNIX timestamp (ms) (If no value is provided, the default value is createTimeMax minus 24 hours)
|
|
195
|
+
self.createTimeMin = None
|
|
196
|
+
# End time for creating a transaction, UNIX timestamp (ms) (If no value is provided, the default value is the current UTC time)
|
|
197
|
+
self.createTimeMax = None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class Web3Api:
|
|
201
|
+
|
|
202
|
+
def __init__(self, config):
|
|
203
|
+
global api_client
|
|
204
|
+
api_client = Client(config)
|
|
205
|
+
|
|
206
|
+
# Create a Web3 Wallet Account
|
|
207
|
+
def createWeb3Account(self, request: CreateWeb3AccountRequest):
|
|
208
|
+
return api_client.send_request(request, '/v1/web3/account/create')
|
|
209
|
+
|
|
210
|
+
# Batch Create Web3 Wallet Accounts
|
|
211
|
+
# Create a batch of wallet accounts based on specified number. Web3 wallet accounts created in batches are not displayed in the Safeheron App by default.
|
|
212
|
+
def batchCreateWeb3Account(self, request: BatchCreateWeb3AccountRequest):
|
|
213
|
+
return api_client.send_request(request, '/v1/web3/batch/account/create')
|
|
214
|
+
|
|
215
|
+
# List Web3 Wallet Accounts
|
|
216
|
+
# Filter Web3 wallet account lists by various conditions.
|
|
217
|
+
def listWeb3Accounts(self, request: ListWeb3AccountRequest):
|
|
218
|
+
return api_client.send_request(request, '/v1/web3/account/list')
|
|
219
|
+
|
|
220
|
+
# Create ethSign
|
|
221
|
+
# Merchants can initiate an ethSign signature through this interface. The merchant is required to serialize the transaction data, generating a corresponding hash (supporting both 0x and non-0x formatted data). The hash is then submitted through this interface to create a signature, which can be obtained by Retrieve a Single Web3 Signature interface or webhook. From there, merchants can complete the subsequent steps according to their own needs once they have obtained the signature.
|
|
222
|
+
def createWeb3EthSign(self, request: CreateWeb3EthSignRequest):
|
|
223
|
+
request.asDict();
|
|
224
|
+
return api_client.send_request(request, '/v1/web3/sign/ethSign')
|
|
225
|
+
|
|
226
|
+
# Create personalSign
|
|
227
|
+
# Merchants can initiate a personalSign signature for any text using this interface. The merchant only needs to prepare the data to be signed and submit it through this interface to create the signature. The resulting signature can then be obtained by Retrieve a Single Web3 Signature interface or via webhook. From there, merchants can complete the subsequent steps according to their own needs once they have obtained the signature.
|
|
228
|
+
def createWeb3PersonalSign(self, request: CreateWeb3PersonalSignRequest):
|
|
229
|
+
request.asDict()
|
|
230
|
+
return api_client.send_request(request, '/v1/web3/sign/personalSign')
|
|
231
|
+
|
|
232
|
+
# Create ethSignTypedData
|
|
233
|
+
# Merchants can initiate an ethSignTypedData signature of specific formatted data (supporting data formats of v1, v3, and v4) through this interface. Merchants will need to format their signature data and submit it through the interface. Once the signature is created, the result can be retrieved via Retrieve a Single Web3 Signature interface or webhook. From there, merchants can complete the subsequent steps according to their own needs once they have obtained the signature.
|
|
234
|
+
def createWeb3EthSignTypedData(self, request: CreateWeb3EthSignTypedDataRequest):
|
|
235
|
+
request.asDict()
|
|
236
|
+
return api_client.send_request(request, '/v1/web3/sign/ethSignTypedData')
|
|
237
|
+
|
|
238
|
+
# Create ethSignTransaction
|
|
239
|
+
# Merchants can initiate ethSignTransaction signature transactions through this interface. The merchant must prepare transaction-related data, such as from, to, nonce, gas limit, gas price, value, data, and more. Once this data is submitted, a signature is created and the result can be obtained by Retrieve a Single Web3 Signature interface or webhook. From there, merchants can complete the subsequent steps according to their own needs once they have obtained the signature.
|
|
240
|
+
def createWeb3EthSignTransaction(self, request: CreateWeb3EthSignTransactionRequest):
|
|
241
|
+
request.asDict()
|
|
242
|
+
return api_client.send_request(request, '/v1/web3/sign/ethSignTransaction')
|
|
243
|
+
|
|
244
|
+
# Cancel Signature
|
|
245
|
+
# Cancel pending signatures.
|
|
246
|
+
def cancelWeb3Sign(self, request: CancelWeb3SignRequest):
|
|
247
|
+
return api_client.send_request(request, '/v1/web3/sign/cancel')
|
|
248
|
+
|
|
249
|
+
# Retrieve a Single Web3 Signature
|
|
250
|
+
# To query a transaction, either customerRefId or txKey are required. If both values are provided, the retrieval will be based on the txKey.
|
|
251
|
+
def oneWeb3Sign(self, request: OneWeb3SignRequest):
|
|
252
|
+
return api_client.send_request(request, '/v1/web3/sign/one')
|
|
253
|
+
|
|
254
|
+
# Web3 Sign Transaction List
|
|
255
|
+
# Filter Web3 Sign history by various conditions.
|
|
256
|
+
def listWeb3Sign(self, request: ListWeb3SignRequest):
|
|
257
|
+
return api_client.send_request(request, '/v1/web3/sign/list')
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.tools import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CoSignerResponse:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# approve
|
|
10
|
+
self.approve = None
|
|
11
|
+
# txKey
|
|
12
|
+
self.txKey = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CoSignerConverter:
|
|
16
|
+
|
|
17
|
+
def __init__(self, config):
|
|
18
|
+
global api_pub_key
|
|
19
|
+
global biz_privKey
|
|
20
|
+
api_pub_key = config['apiPubKey']
|
|
21
|
+
if 'bizPrivKey' in config:
|
|
22
|
+
biz_privKey = PEM_PRIVATE_HEAD + config['bizPrivKey'] + PEM_PRIVATE_END
|
|
23
|
+
if 'bizPrivKeyPemFile' in config:
|
|
24
|
+
private_key_pem_file = config['bizPrivKeyPemFile']
|
|
25
|
+
if private_key_pem_file is not None and private_key_pem_file != '':
|
|
26
|
+
biz_privKey = load_rsa_private_key(private_key_pem_file)
|
|
27
|
+
|
|
28
|
+
def request_convert(self, co_signer_call_back):
|
|
29
|
+
platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + api_pub_key + PEM_PUBLIC_END)
|
|
30
|
+
api_user_rsa_sk = get_rsa_key(biz_privKey)
|
|
31
|
+
required_keys = {
|
|
32
|
+
'key',
|
|
33
|
+
'sig',
|
|
34
|
+
'bizContent',
|
|
35
|
+
'timestamp',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
missing_keys = required_keys.difference(co_signer_call_back.keys())
|
|
39
|
+
if missing_keys:
|
|
40
|
+
raise Exception(co_signer_call_back)
|
|
41
|
+
|
|
42
|
+
# 1 rsa verify
|
|
43
|
+
sig = co_signer_call_back.pop('sig')
|
|
44
|
+
need_sign_message = sort_request(co_signer_call_back)
|
|
45
|
+
v = rsa_verify(platform_rsa_pk, need_sign_message, sig)
|
|
46
|
+
if not v:
|
|
47
|
+
raise Exception("rsa verify: false")
|
|
48
|
+
|
|
49
|
+
# 2 get aes key and iv
|
|
50
|
+
key = co_signer_call_back.pop('key')
|
|
51
|
+
aes_data = rsa_decrypt(api_user_rsa_sk, key)
|
|
52
|
+
aes_key = aes_data[0:32]
|
|
53
|
+
aes_iv = aes_data[32:48]
|
|
54
|
+
|
|
55
|
+
# 3 aes decrypt data, get response data
|
|
56
|
+
r = aes_decrypt(aes_key, aes_iv, b64decode(co_signer_call_back['bizContent']))
|
|
57
|
+
# response_dict['bizContent'] = json.loads(r.decode())
|
|
58
|
+
|
|
59
|
+
return json.loads(r.decode())
|
|
60
|
+
|
|
61
|
+
def response_converter(self, co_signer_response: CoSignerResponse):
|
|
62
|
+
platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + api_pub_key + PEM_PUBLIC_END)
|
|
63
|
+
api_user_rsa_sk = get_rsa_key(PEM_PRIVATE_HEAD + biz_privKey + PEM_PRIVATE_END)
|
|
64
|
+
|
|
65
|
+
ret = dict()
|
|
66
|
+
|
|
67
|
+
# prepare aes key and iv
|
|
68
|
+
aes_key = get_random_bytes(32)
|
|
69
|
+
aes_iv = get_random_bytes(16)
|
|
70
|
+
response_data = json.dumps(co_signer_response.__dict__).replace('\'', '\"').replace('\n', '').encode('utf-8')
|
|
71
|
+
|
|
72
|
+
# 1 rsa encrypt aes key + iv
|
|
73
|
+
aes_data = aes_key + aes_iv
|
|
74
|
+
ret['key'] = rsa_encrypt(platform_rsa_pk, aes_data)
|
|
75
|
+
|
|
76
|
+
# 2 aes encrypt request data
|
|
77
|
+
if response_data is not None:
|
|
78
|
+
aes_encrypted_bytes = aes_encrypt(aes_key, aes_iv, response_data)
|
|
79
|
+
ret['bizContent'] = b64encode(aes_encrypted_bytes).decode()
|
|
80
|
+
|
|
81
|
+
# 3 set timestamp
|
|
82
|
+
ret['timestamp'] = str(int(time.time() * 1000))
|
|
83
|
+
ret['code'] = str('200')
|
|
84
|
+
ret['message'] = str('SUCCESS')
|
|
85
|
+
|
|
86
|
+
# 4 sign request
|
|
87
|
+
need_sign_message = sort_request(ret)
|
|
88
|
+
ret['sig'] = rsa_sign(api_user_rsa_sk, need_sign_message)
|
|
89
|
+
|
|
90
|
+
return ret
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
sys.path.pop(0)
|
|
4
|
+
from safeheron_api_sdk_python.tools import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WebhookConverter:
|
|
8
|
+
|
|
9
|
+
def __init__(self, config):
|
|
10
|
+
global safeheron_webHook_rsa_public_key
|
|
11
|
+
global web_hook_rsa_private_key
|
|
12
|
+
safeheron_webHook_rsa_public_key = config['safeheronWebHookRsaPublicKey']
|
|
13
|
+
if 'webHookRsaPrivateKey' in config:
|
|
14
|
+
web_hook_rsa_private_key = PEM_PRIVATE_HEAD + config['webHookRsaPrivateKey'] + PEM_PRIVATE_END
|
|
15
|
+
if 'webHookRsaPrivateKeyPemFile' in config:
|
|
16
|
+
private_key_pem_file = config['webHookRsaPrivateKeyPemFile']
|
|
17
|
+
if private_key_pem_file is not None and private_key_pem_file != '':
|
|
18
|
+
web_hook_rsa_private_key = load_rsa_private_key(private_key_pem_file)
|
|
19
|
+
|
|
20
|
+
def converter(self, webhook):
|
|
21
|
+
platform_rsa_pk = get_rsa_key(PEM_PUBLIC_HEAD + safeheron_webHook_rsa_public_key + PEM_PUBLIC_END)
|
|
22
|
+
api_user_rsa_sk = get_rsa_key(web_hook_rsa_private_key)
|
|
23
|
+
required_keys = {
|
|
24
|
+
'key',
|
|
25
|
+
'sig',
|
|
26
|
+
'bizContent',
|
|
27
|
+
'timestamp',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
missing_keys = required_keys.difference(webhook.keys())
|
|
31
|
+
if missing_keys:
|
|
32
|
+
raise Exception(webhook)
|
|
33
|
+
|
|
34
|
+
# 1 rsa verify
|
|
35
|
+
sig = webhook.pop('sig')
|
|
36
|
+
need_sign_message = sort_request(webhook)
|
|
37
|
+
v = rsa_verify(platform_rsa_pk, need_sign_message, sig)
|
|
38
|
+
if not v:
|
|
39
|
+
raise Exception("rsa verify: false")
|
|
40
|
+
|
|
41
|
+
# 2 get aes key and iv
|
|
42
|
+
key = webhook.pop('key')
|
|
43
|
+
aes_data = rsa_decrypt(api_user_rsa_sk, key)
|
|
44
|
+
aes_key = aes_data[0:32]
|
|
45
|
+
aes_iv = aes_data[32:48]
|
|
46
|
+
|
|
47
|
+
# 3 aes decrypt data, get response data
|
|
48
|
+
r = aes_decrypt(aes_key, aes_iv, b64decode(webhook['bizContent']))
|
|
49
|
+
# response_dict['bizContent'] = json.loads(r.decode())
|
|
50
|
+
|
|
51
|
+
return json.loads(r.decode())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: safeheron_api_sdk_python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.7
|
|
4
4
|
Summary: Python for Safeheron API
|
|
5
5
|
Home-page: https://github.com/Safeheron/safeheron-api-sdk-python
|
|
6
6
|
Author: safeheron
|
|
@@ -10,5 +10,10 @@ Platform: all
|
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
License-File: LICENSE
|
|
13
|
+
Requires-Dist: Cryptodome
|
|
14
|
+
Requires-Dist: base64
|
|
15
|
+
Requires-Dist: json
|
|
16
|
+
Requires-Dist: time
|
|
17
|
+
Requires-Dist: cryptography
|
|
13
18
|
|
|
14
19
|
# Python SDK for Safeheron API
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
README.rst
|
|
4
|
+
setup.py
|
|
5
|
+
safeheron_api_sdk_python/client.py
|
|
6
|
+
safeheron_api_sdk_python/tools.py
|
|
7
|
+
safeheron_api_sdk_python.egg-info/PKG-INFO
|
|
8
|
+
safeheron_api_sdk_python.egg-info/SOURCES.txt
|
|
9
|
+
safeheron_api_sdk_python.egg-info/dependency_links.txt
|
|
10
|
+
safeheron_api_sdk_python.egg-info/requires.txt
|
|
11
|
+
safeheron_api_sdk_python.egg-info/top_level.txt
|
|
12
|
+
safeheron_api_sdk_python/api/account_api.py
|
|
13
|
+
safeheron_api_sdk_python/api/coin_api.py
|
|
14
|
+
safeheron_api_sdk_python/api/mpc_sign_api.py
|
|
15
|
+
safeheron_api_sdk_python/api/transaction_api.py
|
|
16
|
+
safeheron_api_sdk_python/api/web3_api.py
|
|
17
|
+
safeheron_api_sdk_python/cosigner/co_signer_converter.py
|
|
18
|
+
safeheron_api_sdk_python/webhook/webhook_converter.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
safeheron_api_sdk_python
|
|
@@ -3,15 +3,26 @@ 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.0.
|
|
6
|
+
version='1.0.7',
|
|
7
7
|
description='Python for Safeheron API',
|
|
8
8
|
long_description=long_description,
|
|
9
9
|
author='safeheron',
|
|
10
10
|
author_email='support@safeheron.com',
|
|
11
11
|
url='https://github.com/Safeheron/safeheron-api-sdk-python',
|
|
12
|
-
install_requires=[
|
|
12
|
+
install_requires=[
|
|
13
|
+
'Cryptodome',
|
|
14
|
+
'base64',
|
|
15
|
+
'json',
|
|
16
|
+
'time',
|
|
17
|
+
'cryptography'
|
|
18
|
+
],
|
|
13
19
|
license='MIT License',
|
|
14
|
-
packages=
|
|
20
|
+
packages=[
|
|
21
|
+
'safeheron_api_sdk_python',
|
|
22
|
+
'safeheron_api_sdk_python.api',
|
|
23
|
+
'safeheron_api_sdk_python.cosigner',
|
|
24
|
+
'safeheron_api_sdk_python.webhook'
|
|
25
|
+
],
|
|
15
26
|
platforms=["all"],
|
|
16
27
|
classifiers=[
|
|
17
28
|
'Operating System :: OS Independent',
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
README.rst
|
|
4
|
-
setup.py
|
|
5
|
-
safeheron_api_sdk_python/client.py
|
|
6
|
-
safeheron_api_sdk_python/tools.py
|
|
7
|
-
safeheron_api_sdk_python.egg-info/PKG-INFO
|
|
8
|
-
safeheron_api_sdk_python.egg-info/SOURCES.txt
|
|
9
|
-
safeheron_api_sdk_python.egg-info/dependency_links.txt
|
|
10
|
-
safeheron_api_sdk_python.egg-info/top_level.txt
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/safeheron_api_sdk_python/client.py
RENAMED
|
File without changes
|
{safeheron_api_sdk_python-1.0.5 → safeheron_api_sdk_python-1.0.7}/safeheron_api_sdk_python/tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|