shadowPaySDK 0.1.0__py3-none-any.whl → 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,495 @@
1
+ import shadowPaySDK
2
+ from shadowPaySDK.const import __SHADOWPAY_ABI__ERC20__, __ALLOW_CHAINS__, __SHADOWPAY_CONTRACT_ADDRESS__ERC20__
3
+ from web3 import Web3
4
+ from typing import Optional
5
+ import httpx
6
+
7
+
8
+ class Cheque:
9
+ def __init__(self, w3:Optional[Web3] = None,private_key:Optional[str] = None, ABI = __SHADOWPAY_ABI__ERC20__, allowed_chains = __ALLOW_CHAINS__, retunrn_build_tx:bool = False,address:Optional[str] = None):
10
+ self.w3 = w3
11
+
12
+ self.amount = None
13
+ self.token = None
14
+ self.private_key = private_key
15
+ self.ABI = ABI
16
+ self.address = address
17
+ self.return_build_tx = retunrn_build_tx
18
+ self.allowed_chains = allowed_chains
19
+ if self.w3 != None:
20
+ self.__allow__()
21
+
22
+ def get_id(self, tx):
23
+ if isinstance(tx, str):
24
+ try:
25
+ tx = self.w3.eth.wait_for_transaction_receipt(tx)
26
+ except Exception as e:
27
+ print(f"Failed to get transaction receipt: {str(e)}")
28
+ return False
29
+
30
+ try:
31
+ logs = self.contract.events.ChequeCreated().process_receipt(tx)
32
+ cheque_id = logs[0]["args"]["id"]
33
+ return cheque_id.hex()
34
+ except Exception as e:
35
+ print(f"Failed to get cheque ID from transaction receipt: {str(e)}")
36
+ return False
37
+ def __allow__(self):
38
+ print("Checking if chain is allowed", self.w3.eth.chain_id)
39
+ for chain in self.allowed_chains:
40
+
41
+ if chain == self.w3.eth.chain_id:
42
+ self.get_contract_for_chain(chain_id=self.w3.eth.chain_id)
43
+
44
+ return True
45
+
46
+ raise ValueError(f"Chain {str(self.w3.eth.chain_id)} is not allowed. Allowed chains are: {self.allowed_chains}")
47
+ def get_contract_for_chain(self,chain_id: str):
48
+ c = None
49
+ chain_id = int(chain_id)
50
+
51
+ for key,value in __SHADOWPAY_CONTRACT_ADDRESS__ERC20__.items():
52
+ print("Checking address", value, "for chain_id", chain_id)
53
+ if key == chain_id:
54
+ c = value
55
+ contract_address = Web3.to_checksum_address(c)
56
+ contract = self.w3.eth.contract(address=contract_address, abi=__SHADOWPAY_ABI__ERC20__)
57
+ self.contract = contract
58
+ return contract
59
+ raise ValueError(f"Chain {chain_id} is not supported. Supported chains are: {list(__SHADOWPAY_CONTRACT_ADDRESS__ERC20__.keys())}")
60
+ async def get_address(self):
61
+ if self.address:
62
+ return self.address
63
+ elif self.w3:
64
+ return self.w3.eth.default_account
65
+ else:
66
+ raise ValueError("No address provided or Web3 instance is not set")
67
+
68
+ def set_parameters(self,chain_id: Optional[str] = None, w3:Optional[Web3] = None, amount:Optional[int] = None, private_key:Optional[str] = None, token:Optional[str] = None,address:Optional[str] = None):
69
+ if w3:
70
+ self.w3 = w3
71
+ self.get_contract_for_chain(chain_id=chain_id or self.w3.eth.chain_id)
72
+ if amount:
73
+ self.amount = amount
74
+ if private_key:
75
+ self.private_key = private_key
76
+ self.address = Web3.to_checksum_address(self.w3.eth.account.from_key(private_key).address)
77
+ if token:
78
+ self.token = token
79
+ if address:
80
+ self.address = address
81
+
82
+ def __convert__(self):
83
+ return self.w3.to_wei(self.amount, 'ether')
84
+
85
+ async def InitCheque(self, amount, receiver:list, private_key:Optional[str] = None):
86
+ if not isinstance(receiver,list):
87
+ raise ValueError("Receiver must be a list of addresses, [""0x1234...5678", "0x2345...6789""]")
88
+
89
+ key = private_key or self.private_key
90
+
91
+ if key:
92
+ address = Web3.to_checksum_address(self.w3.eth.account.from_key(key).address)
93
+ print("InitCheque", amount, receiver, key)
94
+
95
+ elif self.address:
96
+ address = Web3.to_checksum_address(self.address)
97
+ else:
98
+ raise ValueError("No private key or address provided")
99
+
100
+
101
+
102
+
103
+
104
+ receiver = [Web3.to_checksum_address(addr) for addr in receiver]
105
+ estimated_gas = self.contract.functions.InitCheque(receiver).estimate_gas({
106
+ 'from': address,
107
+ 'value': self.w3.to_wei(amount, 'ether'),
108
+ 'gasPrice': self.w3.eth.gas_price
109
+ })
110
+ txn = self.contract.functions.InitCheque(receiver).build_transaction({
111
+ 'from': address,
112
+ 'value': self.w3.to_wei(amount, 'ether'),
113
+ 'nonce': self.w3.eth.get_transaction_count(
114
+ address
115
+ ),
116
+ 'gas': estimated_gas,
117
+ 'gasPrice': self.w3.eth.gas_price,
118
+ 'chainId': self.w3.eth.chain_id
119
+ })
120
+ if self.return_build_tx:
121
+ return {
122
+ "build_tx": txn
123
+ }
124
+
125
+ signed_txn = self.w3.eth.account.sign_transaction(txn, key)
126
+ txn_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
127
+ txn_receipt = self.w3.eth.wait_for_transaction_receipt(txn_hash)
128
+ insert_to_dn = None
129
+ logs = self.get_id(txn_receipt)
130
+ if logs:
131
+ cheque_id = logs
132
+ else:
133
+ cheque_id = None
134
+ if txn_receipt.status != 1:
135
+ return False
136
+ return {
137
+ "hash": txn_hash.hex(),
138
+ "chequeId": cheque_id,
139
+ }
140
+
141
+
142
+
143
+
144
+ async def CashOutCheque(
145
+ self,
146
+ private_key: str,
147
+ cheque_id: str
148
+ ):
149
+ if not private_key:
150
+ private_key = self.private_key
151
+
152
+ account = self.w3.eth.account.from_key(private_key)
153
+ sender_address = account.address or self.address
154
+ nonce = self.w3.eth.get_transaction_count(sender_address)
155
+
156
+ latest_block = self.w3.eth.get_block('latest')
157
+ supports_eip1559 = 'baseFeePerGas' in latest_block
158
+
159
+ tx_common = {
160
+ 'from': sender_address,
161
+ 'nonce': nonce,
162
+ 'gas': 300_000,
163
+ }
164
+
165
+ if supports_eip1559:
166
+ # EIP-1559 style
167
+ base_fee = latest_block['baseFeePerGas']
168
+ priority_fee = self.w3.to_wei(2, 'gwei') # можно поднять до 5
169
+ max_fee = base_fee + priority_fee * 2
170
+
171
+ tx_common.update({
172
+ 'maxFeePerGas': max_fee,
173
+ 'maxPriorityFeePerGas': priority_fee
174
+ })
175
+ else:
176
+ # Legacy gas price style
177
+ tx_common.update({
178
+ 'gasPrice': self.w3.to_wei('5', 'gwei')
179
+ })
180
+
181
+ txn = self.contract.functions.CashOutCheque(
182
+ Web3.to_bytes(hexstr=cheque_id)
183
+ ).build_transaction(tx_common)
184
+
185
+ if self.return_build_tx:
186
+ return {"build_tx": txn}
187
+
188
+ signed_txn = self.w3.eth.account.sign_transaction(txn, private_key=private_key)
189
+ tx_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
190
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
191
+
192
+ if receipt.status != 1:
193
+ return False
194
+ return {"hash": tx_hash.hex()}
195
+
196
+ async def InitTokenCheque(self, token_address:str, amount, reciver:str, private_key:Optional[str] = None):
197
+ key = private_key or self.private_key
198
+
199
+ if key:
200
+ address = Web3.to_checksum_address(self.w3.eth.account.from_key(key).address)
201
+
202
+ elif self.address:
203
+ address = Web3.to_checksum_address(self.address)
204
+ else:
205
+ raise ValueError("No private key or address provided")
206
+
207
+
208
+
209
+
210
+
211
+ erc20 = shadowPaySDK.ERC20Token(w3=self.w3)
212
+ erc20.set_params(token_address=token_address)
213
+ decimals = erc20.get_decimals()
214
+ erc20.allowance(
215
+ spender=self.contract.address,
216
+ owner=address,
217
+ )
218
+ estimated_gas = self.contract.functions.InitTokenCheque(
219
+ Web3.to_checksum_address(token_address),
220
+ amount,
221
+ Web3.to_checksum_address(reciver)
222
+ ).estimate_gas({
223
+ 'from': address,
224
+ 'gasPrice': self.w3.eth.gas_price
225
+ })
226
+ txn = self.contract.functions.InitTokenCheque(
227
+ Web3.to_checksum_address(token_address),
228
+ amount,
229
+ Web3.to_checksum_address(reciver)
230
+ ).build_transaction({
231
+ 'from': address,
232
+ 'nonce': self.w3.eth.get_transaction_count(address),
233
+ 'gas': estimated_gas,
234
+ 'gasPrice': self.w3.eth.gas_price
235
+ })
236
+ if self.return_build_tx:
237
+ return {
238
+ "build_tx": txn
239
+ }
240
+ signed_txn = self.w3.eth.account.sign_transaction(txn, key)
241
+ txn_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
242
+ txn_receipt = self.w3.eth.wait_for_transaction_receipt(txn_hash)
243
+
244
+ logs = self.get_id(txn_receipt)
245
+ if logs:
246
+ cheque_id = logs
247
+ else:
248
+ cheque_id = None
249
+ if txn_receipt.status != 1:
250
+ return False
251
+ return {
252
+ "hash": txn_hash.hex(),
253
+ "chequeId": cheque_id,
254
+ }
255
+
256
+ async def CashOutTokenCheque(self, cheque_id: str, private_key: Optional[str] = None):
257
+ if private_key is None:
258
+ private_key = self.private_key
259
+
260
+ account = self.w3.eth.account.from_key(private_key)
261
+
262
+
263
+
264
+ estimated_gas = self.contract.functions.CashOutTokenCheque(
265
+ Web3.to_bytes(hexstr=cheque_id)
266
+ ).estimate_gas({
267
+ 'from': account.address or self.address,
268
+ 'gasPrice': self.w3.eth.gas_price
269
+ })
270
+ txn = self.contract.functions.CashOutTokenCheque(
271
+ Web3.to_bytes(hexstr=cheque_id)
272
+ ).build_transaction({
273
+ 'from': account.address or self.address,
274
+ 'nonce': self.w3.eth.get_transaction_count(account.address or self.address),
275
+ 'gas': estimated_gas,
276
+ 'gasPrice': self.w3.eth.gas_price,
277
+ })
278
+ if self.return_build_tx:
279
+ return {
280
+ "build_tx": txn
281
+ }
282
+
283
+ signed_txn = self.w3.eth.account.sign_transaction(txn, private_key=private_key)
284
+ tx_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
285
+
286
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
287
+
288
+ if receipt.status != 1:
289
+ return False
290
+ return {
291
+ "hash": tx_hash.hex(),
292
+ "status": receipt.status # 1 = success, 0 = fail
293
+ }
294
+ async def InitTokenChequeSwap(self, token_in:str, amount_in,token_out:str, amount_out, reciver:str, private_key:Optional[str] = None):
295
+ key = private_key or self.private_key
296
+ if key:
297
+ address = Web3.to_checksum_address(self.w3.eth.account.from_key(key).address)
298
+ elif self.address:
299
+ address = Web3.to_checksum_address(self.address)
300
+ erc20 = shadowPaySDK.ERC20Token(w3=self.w3)
301
+ erc20.set_params(token_address=token_in)
302
+ approve = erc20.allowance(
303
+ spender=self.contract.address,
304
+ owner=address,
305
+ )
306
+ decimals = erc20.get_decimals()
307
+ erc20.set_params(token_address=token_out)
308
+ token_out_decinals = erc20.get_decimals()
309
+ estimated_gas = self.contract.functions.InitSwapCheque(
310
+ Web3.to_checksum_address(reciver),
311
+ Web3.to_checksum_address(token_in),
312
+ amount_in,
313
+ Web3.to_checksum_address(token_out),
314
+ amount_out,
315
+ ).estimate_gas({
316
+ 'from': address,
317
+ 'gasPrice': self.w3.eth.gas_price
318
+ })
319
+ txn = self.contract.functions.InitSwapCheque(
320
+ Web3.to_checksum_address(reciver),
321
+ Web3.to_checksum_address(token_in),
322
+ amount_in,
323
+ Web3.to_checksum_address(token_out),
324
+ amount_out
325
+ ).build_transaction({
326
+ 'from': address,
327
+ 'nonce': self.w3.eth.get_transaction_count(address),
328
+ 'gas': estimated_gas,
329
+ 'gasPrice': self.w3.eth.gas_price
330
+ })
331
+ if self.return_build_tx:
332
+ return {
333
+ "build_tx": txn
334
+ }
335
+ signed_txn = self.w3.eth.account.sign_transaction(txn, key)
336
+ txn_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
337
+ txn_receipt = self.w3.eth.wait_for_transaction_receipt(txn_hash)
338
+
339
+ logs = self.get_id(txn_receipt)
340
+ if logs:
341
+ cheque_id = logs
342
+ else:
343
+ cheque_id = None
344
+ if txn_receipt.status != 1:
345
+ return False
346
+ return {
347
+ "hash": txn_hash.hex(),
348
+ "chequeId": cheque_id
349
+ }
350
+
351
+ async def CashOutSwapCheque(self, cheque_id: str, private_key: Optional[str] = None):
352
+ swapDetail = await self.getSwaoDetail(cheque_id)
353
+ print(swapDetail)
354
+ if private_key is None:
355
+ private_key = self.private_key
356
+ token_out = swapDetail["tokenOut"]
357
+ amount_out = swapDetail["amountOut"]
358
+ erc20 = shadowPaySDK.ERC20Token(w3=self.w3)
359
+ erc20.set_params(token_address=token_out)
360
+ encure_allowance = erc20.allowance(
361
+ spender=self.contract.address,
362
+ owner=self.address,
363
+ )
364
+ if encure_allowance < amount_out:
365
+ approve = erc20.approve(
366
+ spender=self.contract.address,
367
+ amount=amount_out,
368
+ private_key=private_key,
369
+ conveted_amount=False
370
+ )
371
+ if not approve:
372
+ return False
373
+ print(f"contract balance: {erc20.get_balance(wallet_address=self.contract.address)}")
374
+ estimated_gas = self.contract.functions.CashOutSwapCheque(
375
+ Web3.to_bytes(hexstr=cheque_id)
376
+ ).estimate_gas({
377
+ 'from': self.w3.eth.account.from_key(private_key).address,
378
+ 'gasPrice': self.w3.eth.gas_price
379
+ })
380
+ swa = self.contract.functions.CashOutSwapCheque(
381
+ Web3.to_bytes(hexstr=cheque_id)
382
+ ).build_transaction({
383
+ 'from': self.w3.eth.account.from_key(private_key).address,
384
+ 'nonce': self.w3.eth.get_transaction_count(self.w3.eth.account.from_key(private_key).address),
385
+ 'gas': 300_000,
386
+ 'gasPrice': self.w3.eth.gas_price
387
+ })
388
+ if self.return_build_tx:
389
+ return {
390
+ "build_tx": swa
391
+ }
392
+ signed_txn = self.w3.eth.account.sign_transaction(swa, private_key=private_key)
393
+ tx_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
394
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
395
+ if receipt.status != 1:
396
+ return False
397
+ return {
398
+ "hash": tx_hash.hex(),
399
+ }
400
+
401
+
402
+
403
+
404
+ async def getComunityPool(self):
405
+ fee = self.contract.functions.getCollectedFee().call()
406
+ half_fee_eth = self.w3.from_wei(fee // 2, 'ether')
407
+ return half_fee_eth
408
+ async def getOwner(self):
409
+ return self.contract.functions.getOwner().call()
410
+ async def getTreasery(self):
411
+ return self.contract.functions.getTreasery().call()
412
+ def getChequeInfo(self, cheque_id: str, address: Optional[str] = None):
413
+ ###returns cheque info###
414
+ # s = EVMcheque.getChequeInfo(
415
+ # cheque_id=chequeId,
416
+ # address=address
417
+ # )
418
+ ### cheque_amount = s[0] - amount of cheque in wei
419
+ ### cheque_sender = s[1] - list of sender addresses
420
+ ### cheque_status = s[2] - status of cheque (True - claimed, False - not claimed)
421
+ if not cheque_id:
422
+ raise ValueError("Cheque ID is required")
423
+ if address:
424
+ address = Web3.to_checksum_address(address)
425
+
426
+ cheque_id_bytes32 = Web3.to_bytes(hexstr=cheque_id).rjust(32, b'\x00')
427
+ cheque_info = self.contract.functions.getChequeInfo(
428
+ cheque_id_bytes32,
429
+ address or self.address
430
+ ).call()
431
+
432
+ return cheque_info
433
+ def getTokenChequeInfo(self, cheque_id: str):
434
+ # f = EVMcheque.getTokenChequeInfo(
435
+ # cheque_id=chequeId,
436
+ # )
437
+ ### cheque_sender = s[0] - sender address
438
+ ### cheque_amount = s[1] - receiver address
439
+ ### cheque_status = s[2] - status of cheque (True - claimed, False - not claimed
440
+
441
+ if not cheque_id:
442
+ raise ValueError("Cheque ID is required")
443
+
444
+ cheque_id_bytes32 = Web3.to_bytes(hexstr=cheque_id).rjust(32, b'\x00')
445
+ cheque_info = self.contract.functions.getTokenChequeInfo(cheque_id_bytes32).call({
446
+ cheque_id_bytes32
447
+ })
448
+ return cheque_info
449
+ async def getSwaoDetail(self, cheque_id: str):
450
+ # f = EVMcheque.getSwaoDetail(
451
+ # cheque_id=chequeId,
452
+ # )
453
+ # f[0] - tokenOut address,
454
+ # f[1] - amountOut in wei,
455
+ # f[2] - spender,
456
+ # f[3] - receiver,
457
+ # f[4] - claimed
458
+ cheque_id_bytes32 = Web3.to_bytes(hexstr=cheque_id).rjust(32, b'\x00')
459
+ s = self.contract.functions.getSwapDetail(cheque_id_bytes32).call()
460
+ return {
461
+ "tokenOut": s[0],
462
+ "amountOut": s[1],
463
+ }
464
+
465
+ class NFTcheque:
466
+ def __init__(self, w3:Web3, token:str, amount:int, spender:str):
467
+ self.w3 = w3
468
+ self.token = token
469
+ self.amount = amount
470
+ self.spender = spender
471
+
472
+ def InitNFTCheque(self):
473
+ pass
474
+
475
+ def CashOutNFTCheque(self):
476
+ pass
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+