shadowPaySDK 0.2.1__tar.gz → 16.7.2025__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 (26) hide show
  1. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/PKG-INFO +20 -7
  2. shadowpaysdk-16.7.2025/README.md +21 -0
  3. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/setup.py +6 -6
  4. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/__init__.py +1 -3
  5. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/const.py +15 -3
  6. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/interface/__init__.py +2 -2
  7. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/interface/erc20.py +29 -18
  8. shadowpaysdk-16.7.2025/shadowPaySDK/interface/sol.py +230 -0
  9. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/types/EVMcheque.py +166 -74
  10. shadowpaysdk-16.7.2025/shadowPaySDK/types/SOLcheque.py +284 -0
  11. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK.egg-info/PKG-INFO +20 -7
  12. shadowpaysdk-16.7.2025/shadowPaySDK.egg-info/requires.txt +6 -0
  13. shadowpaysdk-0.2.1/README.md +0 -8
  14. shadowpaysdk-0.2.1/shadowPaySDK/interface/sol.py +0 -162
  15. shadowpaysdk-0.2.1/shadowPaySDK/types/SOLcheque.py +0 -27
  16. shadowpaysdk-0.2.1/shadowPaySDK.egg-info/requires.txt +0 -6
  17. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/LICENSE +0 -0
  18. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/setup.cfg +0 -0
  19. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/api.py +0 -0
  20. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/interface/erc721.py +0 -0
  21. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/types/__init__.py +0 -0
  22. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/utils/__init__.py +0 -0
  23. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK/utils/utils.py +0 -0
  24. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK.egg-info/SOURCES.txt +0 -0
  25. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK.egg-info/dependency_links.txt +0 -0
  26. {shadowpaysdk-0.2.1 → shadowpaysdk-16.7.2025}/shadowPaySDK.egg-info/top_level.txt +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shadowPaySDK
3
- Version: 0.2.1
3
+ Version: 16.7.2025
4
4
  Summary: ShadowPay SDK for ERC20/ERC721 and P2P smart contract interaction
5
- Author: dazarius_
5
+ Author: dazay(aka dazarius_)
6
6
  Author-email: your@email.com
7
7
  License: MIT
8
8
  Classifier: Programming Language :: Python :: 3
@@ -11,10 +11,10 @@ Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: web3>=6.0.0
15
- Requires-Dist: requests>=2.28.0
16
- Requires-Dist: solana==0.36.7
17
- Requires-Dist: anchorpy>=0.21.0
14
+ Requires-Dist: web3
15
+ Requires-Dist: requests
16
+ Requires-Dist: solana
17
+ Requires-Dist: anchorpy
18
18
  Requires-Dist: solders
19
19
  Requires-Dist: httpx==0.28.1
20
20
  Dynamic: author
@@ -28,11 +28,24 @@ Dynamic: requires-dist
28
28
  Dynamic: requires-python
29
29
  Dynamic: summary
30
30
 
31
- # shadowPayS
31
+ # shadowPaySdk
32
32
 
33
33
  ```bash
34
34
  pip3 install shadowPaySDK
35
+ pip3 install --break-system-packages git+https://github.com/dazarius/SDK.git
35
36
  ```
37
+ ```example to use cheque
38
+
39
+
40
+
41
+
42
+
43
+ import shadowPaySDK
44
+
45
+
46
+ EVMcheque = shadowPaySDK.Cheque(
47
+ retunrn_build_tx=True
48
+ )
36
49
 
37
50
 
38
51
 
@@ -0,0 +1,21 @@
1
+ # shadowPaySdk
2
+
3
+ ```bash
4
+ pip3 install shadowPaySDK
5
+ pip3 install --break-system-packages git+https://github.com/dazarius/SDK.git
6
+ ```
7
+ ```example to use cheque
8
+
9
+
10
+
11
+
12
+
13
+ import shadowPaySDK
14
+
15
+
16
+ EVMcheque = shadowPaySDK.Cheque(
17
+ retunrn_build_tx=True
18
+ )
19
+
20
+
21
+
@@ -2,11 +2,11 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='shadowPaySDK',
5
- version='0.2.1',
5
+ version='16.07.2025',
6
6
  description='ShadowPay SDK for ERC20/ERC721 and P2P smart contract interaction',
7
7
  long_description=open('README.md').read(),
8
8
  long_description_content_type='text/markdown',
9
- author='dazarius_',
9
+ author='dazay(aka dazarius_)',
10
10
  author_email='your@email.com',
11
11
  license='MIT',
12
12
  packages=find_packages(),
@@ -16,10 +16,10 @@ setup(
16
16
  'Operating System :: OS Independent',
17
17
  ],
18
18
  install_requires=[
19
- 'web3>=6.0.0',
20
- 'requests>=2.28.0',
21
- 'solana==0.36.7',
22
- 'anchorpy>=0.21.0',
19
+ 'web3',
20
+ 'requests',
21
+ 'solana',
22
+ 'anchorpy',
23
23
 
24
24
  'solders',
25
25
  'httpx==0.28.1'
@@ -1,12 +1,10 @@
1
1
  import json
2
2
  from shadowPaySDK.interface.erc20 import ERC20Token
3
3
  from shadowPaySDK.interface.erc721 import ERC721Token
4
- from shadowPaySDK.interface.sol import SolTokens
5
- from shadowPaySDK.interface.sol import SOL
4
+ from shadowPaySDK.interface.sol import SOL as sol
6
5
  from shadowPaySDK.types.EVMcheque import Cheque
7
6
  from shadowPaySDK.types.SOLcheque import SOLCheque
8
7
  from shadowPaySDK.const import __ERC20_ABI__, __SHADOWPAY_ABI__ERC20__,__ALLOW_CHAINS__, __SHADOWPAY_CONTRACT_ADDRESS__ERC20__
9
- from shadowPaySDK.api import __MAIN__URL__, __CREATE__CHEQUE__, get_my_cheques, create_cheque
10
8
 
11
9
 
12
10
  # from shadowPaySDK.utils import parse_tx as PARSE_TX
@@ -1,5 +1,5 @@
1
1
  import json
2
-
2
+ from solders.pubkey import Pubkey
3
3
  __ALLOW_CHAINS__ = [
4
4
  56, # BSC Mainnet
5
5
  97, # BSC Testnet
@@ -11,6 +11,9 @@ __ALLOW_CHAINS__ = [
11
11
  0xa
12
12
  ]
13
13
 
14
+
15
+
16
+
14
17
  __VERSION__ = "0.1.2"
15
18
 
16
19
 
@@ -27,7 +30,7 @@ __ERC20_ABI__ = json.loads("""[
27
30
  ]""")
28
31
 
29
32
  __SHADOWPAY_CONTRACT_ADDRESS__ERC20__ = {
30
- 97: "0x17a82E53a3b3f2acA7ceae8CA6B6b3B8F14e4441"
33
+ 97: "0x5487C0DdCbD5465F26B446c6CAB88D8d6F7DF23b"
31
34
  }
32
35
 
33
36
  __SHADOWPAY_ABI__ERC20__= json.loads("""[
@@ -543,4 +546,13 @@ __SHADOWPAY_ABI__ERC20__= json.loads("""[
543
546
  __SHADOWPAY_ABI__ERC721__ = json.loads("""[]""")
544
547
  __SHADOWPAY_CONTRACT_ADDRESS__ERC721__ = {
545
548
  "0x1": "0x3c5b8d6f2e"
546
- }
549
+ }
550
+
551
+ SOLANA_SYSTEM_PROGRAMM = "11111111111111111111111111111111"
552
+ LAMPORTS_PER_SOL = 1_000_000_000
553
+ WRAPED_SOL = "So11111111111111111111111111111111111111112"
554
+ TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
555
+ NATIVE_DECIMALS: int = 9
556
+ PROGRAM_ID = Pubkey.from_string("CrfYLvU4FdVjkBno2rRi6u5U6nGCykpQnQKSBg3uVXTw")
557
+
558
+ CONFIG_PDA=Pubkey.find_program_address([b"config"], PROGRAM_ID)
@@ -1,4 +1,4 @@
1
1
  from .erc20 import ERC20Token as ERC20
2
2
  from .erc721 import ERC721Token as ERC721
3
- from .sol import SolTokens as SPL
4
- __all__ = ["ERC20", "ERC721", "SPL"]
3
+ from .sol import SOL as sol
4
+ __all__ = ["ERC20", "ERC721", "sol"]
@@ -6,9 +6,10 @@ from shadowPaySDK.const import __ERC20_ABI__
6
6
 
7
7
 
8
8
  class ERC20Token:
9
- def __init__(self, w3:Web3, explorer: Optional[str] = None):
9
+ def __init__(self, w3: Optional[Web3] = None, explorer: Optional[str] = None):
10
10
  self.web3 = w3
11
11
  self.explorer = explorer
12
+
12
13
  self.address = None
13
14
  self.contract = None
14
15
 
@@ -21,7 +22,7 @@ class ERC20Token:
21
22
 
22
23
  def _ensure_contract(self):
23
24
  if not self.contract:
24
- raise ValueError("Token address is not set. Use set_token(token_address) first.")
25
+ raise ValueError("Token address is not set. Use set_params first.")
25
26
 
26
27
  def _format_tx(self, tx_hash: str) -> str:
27
28
  if self.explorer:
@@ -30,10 +31,9 @@ class ERC20Token:
30
31
  def gen_wallet(self) -> str:
31
32
  account = self.web3.eth.account.create()
32
33
  return account
33
- def get_decimals(self, token) -> int:
34
+ def get_decimals(self) -> int:
34
35
  self._ensure_contract()
35
- if token:
36
- self.set_params(token_address=token)
36
+
37
37
  return self.contract.functions.decimals().call()
38
38
 
39
39
  def get_symbol(self) -> str:
@@ -45,21 +45,21 @@ class ERC20Token:
45
45
  raw = self.contract.functions.balanceOf(Web3.to_checksum_address(wallet_address)).call()
46
46
  return raw / (10 ** self.get_decimals())
47
47
 
48
- def allowance(self, owner: str, spender: str, token) -> float:
48
+ def allowance(self, owner: str, spender: str) -> float:
49
49
  self._ensure_contract()
50
50
  raw = self.contract.functions.allowance(
51
51
  Web3.to_checksum_address(owner),
52
52
  Web3.to_checksum_address(spender)
53
53
  ).call()
54
- return raw / (10 ** self.get_decimals(token))
54
+ return raw / (10 ** self.get_decimals())
55
55
 
56
- def ensure_allowance(self, private_key: str, spender: str, amount, token) -> Union[bool, str]:
56
+ def ensure_allowance(self, private_key: str, spender: str, amount) -> Union[bool, str]:
57
57
  self._ensure_contract()
58
58
  account = self.web3.eth.account.from_key(private_key)
59
- current = self.allowance(account.address, spender, token)
59
+ current = self.allowance(account.address, spender)
60
60
  if current == amount:
61
61
  return True
62
- return self.approve(private_key, spender, amount, token)
62
+ return self.approve(private_key, spender, amount)
63
63
 
64
64
  def transfer(self, private_key: str, to: str, amount: float) -> str:
65
65
  self._ensure_contract()
@@ -87,28 +87,39 @@ class ERC20Token:
87
87
  tx_hash = self.web3.eth.send_raw_transaction(signed.raw_transaction)
88
88
  return self._format_tx(self.web3.to_hex(tx_hash))
89
89
 
90
- def approve(self, private_key: str, spender: str, amount: float, token) -> str:
90
+ def approve(self, spender: str, amount: float,address:Optional[str] = None, private_key: Optional[str] = None, build_tx: bool = False) -> str:
91
+
91
92
  self._ensure_contract()
92
- account = self.web3.eth.account.from_key(private_key)
93
- decimals = self.get_decimals(token=token)
93
+ key = private_key
94
+
95
+ if key:
96
+ address = Web3.to_checksum_address(self.web3.eth.account.from_key(key).address)
97
+
98
+ elif self.address:
99
+ address = Web3.to_checksum_address(self.address)
100
+ else:
101
+ raise ValueError("No private key or address provided")
102
+
103
+ decimals = self.get_decimals()
94
104
  amount = int(amount * (10 ** decimals))
95
105
 
96
106
  txn = self.contract.functions.approve(
97
107
  Web3.to_checksum_address(spender),
98
108
  amount
99
109
  ).build_transaction({
100
- 'from': account.address,
101
- 'nonce': self.web3.eth.get_transaction_count(account.address),
110
+ 'from': address,
111
+ 'nonce': self.web3.eth.get_transaction_count(address),
102
112
  'gas': 60000,
103
113
 
104
114
  'gasPrice': self.web3.eth.gas_price,
105
115
  })
116
+ if build_tx:
117
+ return txn
106
118
 
107
- signed = self.web3.eth.account.sign_transaction(txn, private_key)
119
+ signed = self.web3.eth.account.sign_transaction(txn, key)
108
120
  tx_hash = self.web3.eth.send_raw_transaction(signed.raw_transaction)
109
121
  tx_receipt = self.web3.eth.wait_for_transaction_receipt(tx_hash)
110
122
  if tx_receipt.status != 1:
111
123
  raise ValueError(f"aaprove fail.\n {self._format_tx(self.web3.to_hex(tx_hash))}")
112
-
113
- return f"approve: {self._format_tx(self.web3.to_hex(tx_hash))}"
124
+ return f"{self._format_tx(self.web3.to_hex(tx_hash))}"
114
125
 
@@ -0,0 +1,230 @@
1
+ import asyncio
2
+ import solana
3
+ from solana.rpc.async_api import AsyncClient, GetTokenAccountsByOwnerResp
4
+ from solders.transaction import Transaction
5
+ from solders.system_program import TransferParams as p
6
+ import spl
7
+ import spl.token
8
+ import spl.token.constants
9
+ from spl.token.instructions import get_associated_token_address, create_associated_token_account, transfer, close_account, TransferParams
10
+ from solders.system_program import transfer as ts
11
+ from solders.system_program import TransferParams as tsf
12
+ from spl.token.constants import TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID
13
+ from solana.rpc.types import TxOpts, TokenAccountOpts
14
+ from solana.rpc.types import TxOpts
15
+ import solders
16
+ from solders.message import Message
17
+
18
+ # from solders.pubkey import Pubkey
19
+ # from solders.keypair import Keypair
20
+ # from solders.signature import Signature
21
+ # from solders.transaction import Transaction
22
+ from spl.token.async_client import AsyncToken
23
+
24
+
25
+ from solana.rpc.commitment import Confirmed
26
+ from solana.rpc.async_api import AsyncClient
27
+ import anchorpy
28
+ from anchorpy import Provider, Wallet, Idl
29
+ from typing import Optional, Union
30
+ import pprint
31
+ import httpx
32
+ import base64
33
+ import re
34
+
35
+
36
+ LAMPORTS_PER_SOL = 1_000_000_000 # 1 SOL = 1,000,000,000 lamports
37
+
38
+ class SOL:
39
+ def __init__(self, rpc_url = "https://api.mainnet-beta.solana.com", KEYPAIR: Optional[Union[str, solders.keypair.Keypair]] = None,TOKEN_MINT: Optional[str] = None):
40
+ self.rpc_url = rpc_url
41
+
42
+ self.client = AsyncClient(rpc_url)
43
+ self.KEYPAIR = None
44
+ self.PROGRAM_ID = TOKEN_PROGRAM_ID # Default to the SPL Token Program ID
45
+ self.TOKEN_MINT = TOKEN_MINT
46
+ self.WRAPED_SOL_ID = spl.token.constants.WRAPPED_SOL_MINT
47
+ if KEYPAIR:
48
+ self.set_keypair(KEYPAIR)
49
+
50
+ def set_keypair(self, KEYPAIR: Union[str, solders.keypair.Keypair]):
51
+ if isinstance(KEYPAIR, str):
52
+ try:
53
+ self.KEYPAIR = solders.keypair.Keypair.from_base58_string(KEYPAIR)
54
+ except Exception as e:
55
+ raise ValueError(f"Invalid Keypair string: {e}")
56
+ elif isinstance(KEYPAIR, solders.keypair.Keypair):
57
+ self.KEYPAIR = KEYPAIR
58
+ else:
59
+ raise ValueError("KEYPAIR must be a Keypair instance or a base58 encoded string.")
60
+
61
+ def set_params(self, rpc_url: Optional[str] = None, KEYPAIR: Optional[Union[str, solders.keypair.Keypair]] = None,TOKEN_MINT: Optional[str] = None):
62
+ if rpc_url:
63
+ self.rpc_url = rpc_url
64
+ self.client = AsyncClient(rpc_url)
65
+ if KEYPAIR:
66
+ self.set_keypair(KEYPAIR)
67
+ if TOKEN_MINT:
68
+ self.TOKEN_MINT = TOKEN_MINT
69
+
70
+ def get_pubkey(self, returnString: Optional[bool] = None):
71
+
72
+
73
+ if self.KEYPAIR:
74
+ pubkey = self.KEYPAIR.pubkey()
75
+ pubkey_str = str(pubkey)
76
+ if returnString:
77
+ return pubkey_str
78
+ return pubkey
79
+
80
+ raise ValueError("Keypair not set")
81
+
82
+ def gen_wallet(self):
83
+ return solders.keypair.Keypair()
84
+ async def get_balance(self):
85
+ resp = await self.client.get_balance(self.get_pubkey())
86
+ lamports = resp.value
87
+ sol_balance = lamports / LAMPORTS_PER_SOL
88
+ return sol_balance
89
+ async def get_token_accounts_by_owner(self,owner_pubkey: Optional[str] = None):
90
+ if not owner_pubkey:
91
+ print("No owner pubkey provided, using the wallet's pubkey.")
92
+ owner_pubkey = self.get_pubkey(returnString=True)
93
+ headers = {
94
+ "Content-Type": "application/json",
95
+ }
96
+ body = {
97
+ "jsonrpc": "2.0",
98
+ "id": 1,
99
+ "method": "getTokenAccountsByOwner",
100
+ "params": [
101
+ str(owner_pubkey),
102
+ {"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},
103
+ {"encoding": "jsonParsed"}
104
+ ]
105
+ }
106
+ async with httpx.AsyncClient() as client:
107
+ response = await client.post(self.rpc_url, headers=headers, json=body)
108
+ result = response.json()
109
+ accounts = result["result"]["value"]
110
+
111
+ token_data = {}
112
+ for acc in accounts:
113
+ parsed = acc["account"]["data"]["parsed"]["info"]
114
+ mint = parsed["mint"]
115
+ ui_amount = parsed["tokenAmount"]["uiAmount"]
116
+ token_data[mint] = {"amount": ui_amount}
117
+
118
+
119
+
120
+ return token_data
121
+ async def is_connected(self):
122
+ return await self.client.is_connected()
123
+
124
+ async def close(self):
125
+ await self.client.close()
126
+
127
+ async def fetch_metadata_raw(self,mint_address: str):
128
+ METADATA_PROGRAM_ID = solders.pubkey.Pubkey.from_string("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")
129
+ mint = solders.pubkey.Pubkey.from_string(mint_address)
130
+ seeds = [
131
+ b"metadata",
132
+ bytes(METADATA_PROGRAM_ID),
133
+ bytes(mint),
134
+ ]
135
+ pda, _ = solders.pubkey.Pubkey.find_program_address(seeds, METADATA_PROGRAM_ID)
136
+
137
+ payload = {
138
+ "jsonrpc": "2.0",
139
+ "id": 1,
140
+ "method": "getAccountInfo",
141
+ "params": [
142
+ str(pda),
143
+ {"encoding": "base64"}
144
+ ]
145
+ }
146
+
147
+ async with httpx.AsyncClient() as client:
148
+ r = await client.post(self.rpc_url, json=payload)
149
+ data = r.json()
150
+
151
+ if not data["result"]["value"]:
152
+ return None
153
+
154
+ b64_data = data["result"]["value"]["data"][0]
155
+ raw_bytes = base64.b64decode(b64_data)
156
+
157
+ name = raw_bytes[1+32+32 : 1+32+32+32].decode("utf-8").rstrip("\x00")
158
+ name = re.sub(r'[^\x20-\x7E]', '', name)
159
+ return {
160
+ "mint": mint_address,
161
+ "name": name,
162
+
163
+
164
+ }
165
+ async def transfer_token(self, to: str, amount: float):
166
+
167
+ if not self.TOKEN_MINT:
168
+ raise ValueError("not set TOKEN_MINT.")
169
+ if not self.KEYPAIR:
170
+ raise ValueError("not set KEYPAIR.")
171
+
172
+ sender_pubkey = self.get_pubkey()
173
+ receiver_pubkey = solders.pubkey.Pubkey.from_string(to)
174
+ token_pubkey = solders.pubkey.Pubkey.from_string(self.TOKEN_MINT)
175
+
176
+ token = AsyncToken(self.client, token_pubkey, TOKEN_PROGRAM_ID, self.KEYPAIR)
177
+ sender_ata = get_associated_token_address(sender_pubkey, token_pubkey)
178
+ receiver_ata = get_associated_token_address(receiver_pubkey, token_pubkey)
179
+
180
+ tx = Transaction()
181
+
182
+ res = await self.client.get_account_info(receiver_ata)
183
+ if res.value is None:
184
+ tx.add(
185
+ create_associated_token_account(
186
+ payer=sender_pubkey,
187
+ owner=receiver_pubkey,
188
+ mint=token_pubkey
189
+ )
190
+ )
191
+
192
+ decimals = (await token.get_mint_info()).decimals
193
+ real_amount = int(amount * (10 ** decimals))
194
+ params = TransferParams(
195
+ program_id=TOKEN_PROGRAM_ID,
196
+ source=sender_ata,
197
+ dest=receiver_ata,
198
+ owner=sender_pubkey,
199
+ amount=real_amount
200
+ )
201
+
202
+ tx.add(transfer(params))
203
+
204
+ resp = await self.client.send_transaction(tx, self.KEYPAIR, opts=TxOpts(skip_preflight=True, preflight_commitment=Confirmed))
205
+ return resp.value
206
+
207
+
208
+ async def transfer_native(self, to:str, amount: int):
209
+ if not self.KEYPAIR:
210
+ raise ValueError("not set KEYPAIR.")
211
+
212
+ sender_pubkey = self.get_pubkey()
213
+ receiver_pubkey = solders.pubkey.Pubkey.from_string(to)
214
+ ixns = [
215
+ ts(tsf(
216
+ from_pubkey=sender_pubkey,
217
+ to_pubkey=receiver_pubkey,
218
+ lamports=int(amount * LAMPORTS_PER_SOL)
219
+ ))
220
+ ]
221
+ msg = Message(ixns, self.get_pubkey())
222
+ latest_blockhash_resp = await self.client.get_latest_blockhash()
223
+
224
+ blockhash_str = latest_blockhash_resp.value.blockhash
225
+ tx = Transaction([self.KEYPAIR], msg, blockhash_str)
226
+ resp = await self.client.send_transaction(tx)
227
+ return resp.value
228
+
229
+
230
+