Welcome to py-near’s documentation!
Quick start
At first you have to import all necessary modules
from pynear.account import Account
Then you have to initialize Account
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
Next step: check account balance
import asyncio
from pynear.dapps.core import NEAR
async def main():
await acc.startup()
print(await acc.get_balance() / NEAR)
print(await acc.get_balance("bob.near") / NEAR)
asyncio.run(main())
Next step: send 2 NEAR to bob.near
tr = await acc.send_money("bob.near", NEAR * 2)
print(tr.transaction.hash)
print(tr.logs)
Next step: send 2 NEAR to bob.near no waiting for transaction confirmation
transaction_hash = await acc.send_money("bob.near", NEAR * 2, nowait=True)
print(transaction_hash)
Next step: send 0.1 NEAR by phone number
tr = await acc.phone.send_near_to_phone("+15626200110", NEAR // 10)
print(tr.transaction.hash)
Summary
from pynear.account import Account
import asyncio
from pynear.dapps.core import NEAR
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
async def main():
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
await acc.startup()
print(await acc.get_balance() / NEAR)
print(await acc.get_balance("bob.near") / NEAR)
tr = await acc.send_money("bob.near", NEAR * 2)
print(tr.transaction.hash)
print(tr.logs)
tr = await acc.phone.send_near_to_phone("+15626200911", NEAR // 10)
print(tr.transaction.hash)
asyncio.run(main())
Parallel requests
Only one parallel request can be made from one private key. All transaction calls execute sequentially. To make several parallel calls you need to use several private keys
Add 2 new full access keys:
acc = Account("bob.near", private_key1)
for i in range(2):
signer = InMemorySigner.from_random(AccountId("bob.near"), KeyType.ED25519)
await acc.add_full_access_public_key(str(signer.public_key))
print(signer.secret_key)
Now we can call transactions in parallel
acc = Account("bob.near", [private_key1, private_key2, private_key3])
# request time = count transactions / count public keys
tasks = [
asyncio.create_task(acc.send_money("alisa.near", 1)),
asyncio.create_task(acc.send_money("alisa.near", 1)),
asyncio.create_task(acc.send_money("alisa.near", 1)),
]
for t in task:
await t
Account
Quick start
from pynear.account import Account
import asyncio
from pynear.dapps.core import NEAR
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
async def main():
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
await acc.startup()
print(await acc.get_balance() / NEAR)
print(await acc.get_balance("bob.near") / NEAR)
transaction = await acc.send_money("bob.near", NEAR * 2)
print(tr.transaction.hash)
print(tr.logs)
transaction = await acc.phone.send_near_to_phone("+15626200911", NEAR // 10)
print(tr.transaction.hash)
asyncio.run(main())
Documentation
- class Account
This class implement all blockchain functions for your account. Only one parallel request can be made from one private key. All transaction calls execute sequentially.
acc = Account("bob.near", private_key1) # requests time ~18s tasks = [ asyncio.create_task(acc.send_money("alisa.near", 1)), asyncio.create_task(acc.send_money("alisa.near", 1)), asyncio.create_task(acc.send_money("alisa.near", 1)), ] for t in task: await t
Account() support multikeys. In this case you can make a few parallel requests.
acc = Account("bob.near", [private_key1, private_key2, private_key3]) # requests time ~6s tasks = [ asyncio.create_task(acc.send_money("alisa.near", 1)), asyncio.create_task(acc.send_money("alisa.near", 1)), asyncio.create_task(acc.send_money("alisa.near", 1)), ] for t in task: await t
- get_access_key()
Get access key for current account
- Returns:
AccountAccessKey
await acc.get_access_key()
- get_access_key_list(account_id=None)
Send fungible token to phone number. Reciver will get sms with link to claim tokens. Get access key list for account_id, if account_id is None, get access key list for current account
- Parameters:
account_id – if account_id is None, return balance of current account
- Returns:
list of PublicKey
keys = await acc.get_access_key_list() print(len(keys))
- fetch_state(phone)
Fetch state for given account
- Returns:
state dict
state = await acc.fetch_state() print(state)
- send_money(account_id: str, amount: int, nowait=False)
Send money to account_id
- Parameters:
account_id – receiver account id
amount – amount in yoctoNEAR
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.send_money('bob.near', NEAR * 3)
- view_function(contract_id: str, method_name: str, args: dict)
Call view function on smart contract. View function is read only function, it can’t change state
- Parameters:
contract_id – smart contract account id
method_name – method name to call
args – json args to call method
- Returns:
result of view function call
result = await acc.view_function("usn.near", "ft_balance_of", {"account_id": "bob.near"}) print(result)
- function_call(contract_id: str, method_name: str, args: dict, gas=DEFAULT_ATTACHED_GAS, amount=0, nowait=False)
Call function on smart contract
- Parameters:
contract_id – smart contract adress
method_name – call method name
args – json params for method
gas – amount of attachment gas
amount – amount of attachment NEAR
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.function_call('usn.near', "ft_transfer", {"receiver_id": "bob.near", "amount": "1000000000000000000000000"})
- create_account(account_id: str, public_key: Union[str, bytes], initial_balance: int, nowait=False)
- Create new account in subdomian of current account. For example, if current account is “test.near”,
you can create “wwww.test.near”
- Parameters:
account_id – new account id
public_key – add public key to new account
initial_balance – amount to transfer NEAR to new account
nowait – is nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.create_account('test.bob.near', "5X9WvUbRV3aSd9Py1LK7HAndqoktZtcgYdRjMt86SxMj", NEAR * 3)
- add_public_key(public_key: Union[str, bytes], receiver_id: str, method_names: List[str] = None, allowance: int = 25000000000000000000000, nowait=False)
Add public key to account with access to smart contract methods
- Parameters:
public_key – public_key to add
receiver_id – smart contract account id
method_names – list of method names to allow
allowance – maximum amount of gas to use for this key
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.add_public_key("5X9WvUbRV3aSd9Py1LK7HAndqoktZtcgYdRjMt86SxMj", "usn.near", [])
- add_full_access_public_key(public_key: Union[str, bytes], nowait=False)
Add public key to account with full access
- Parameters:
public_key – public_key to add
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.add_full_access_public_key("5X9WvUbRV3aSd9Py1LK7HAndqoktZtcgYdRjMt86SxMj")
- delete_public_key(public_key: Union[str, bytes], nowait=False)
Delete public key from account
- Parameters:
public_key – public_key to delete
nowait – is nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.delete_public_key("5X9WvUbRV3aSd9Py1LK7HAndqoktZtcgYdRjMt86SxMj")
- deploy_contract(contract_code: bytes, nowait=False)
Deploy smart contract to account
- Parameters:
contract_code – smart contract code
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
with open("contract.wasm", "rb") as f: contract_code = f.read() await acc.deploy_contract(contract_code, nowait=True)
- stake(contract_code: bytes, nowait=False)
Stake NEAR on account. Account must have enough balance to be in validators pool
- Parameters:
public_key – public_key to stake
amount – amount of NEAR to stake
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
- get_balance(account_id: str = None)
Get account balance
- Parameters:
account_id – if account_id is None, return balance of current account
- Returns:
balance of account in yoctoNEAR
result = await acc.get_balance("usn.near") print(result)
- property phone
Get client for phone.herewallet.near
- Returns:
Phone(self)
- property ft
Get client for fungible tokens
- Returns:
FT(self)
Phone number transfer
Note
Phone number transfer available only for mainnet
Quick start
from pynear.account import Account
from pynear.dapps.fts import FTS
import asyncio
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
async def main():
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
await acc.startup()
transaction = await acc.phone.send_ft_to_phone(FTS.USDC, "+15626200911", 1)
print(tr.transaction.hash)
asyncio.run(main())
Documentation
- class Phone(DappClient)
Client to phone.herewallet.near contract With this contract you can send NEAR and fungible tokens to phone number. Reciver will get notification with link to claim tokens.
acc = Account(...) phone = acc.phone await acc.phone.send_near_to_phone("+1234567890", NEAR * 2, "Happy birthday!")
- send_near_to_phone(phone: str, amount: float, comment: str = '', nowait: bool = False)
Send NEAR to phone number. Reciver will get sms with link to claim tokens.
- Parameters:
phone – +X format phone number
amount – number of NEAR which will be sent
comment – any comment
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.phone.send_near_to_phone('+79999999999', NEAR * 2*)
- send_ft_to_phone(ft: FtModel, phone: str, amount: float, comment: str = '', nowait: bool = False)
Send fungible token to phone number. Reciver will get sms with link to claim tokens.
- Parameters:
ft – Fungible token model
phone – +X format phone number
amount – number of FT which will be sent
comment –
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
# Send 1 USDC to phone number await acc.phone.send_ft_to_phone(FTS.USDC, '+79999999999', 1)
- get_ft_transfers(phone)
Get list of fungible token transfers to phone number :param phone: phone number :return: list of FtTrustTransaction
await acc.phone.get_ft_transfers('+79999999999')
- get_near_transfers(phone)
Get list of NEAR transfers to phone number
- Parameters:
phone – phone number
- Returns:
list of NEAR transfers
await acc.phone.get_near_transfers('+79999999999')
- cancel_near_transaction(phone: str, index: int)
Cancel NEAR transfer to phone number. Use index from get_near_transfers() method
- Parameters:
phone – phone number
index – index in transaction list
- Returns:
await acc.phone.cancel_near_transaction('+79999999999', 0)
- cancel_ft_transaction(phone: str, index: int)
Cancel NEAR transfer to phone number. Use index from get_near_transfers() method
Cancel fungible token transfer to phone number. Use index from get_ft_transfers() method
- Parameters:
phone – phone number
index – index in transaction list
- Returns:
await acc.phone.cancel_ft_transaction('+79999999999', 0)
Fungible tokens
Quick start
from pynear.account import Account
from pynear.dapps.fts import FTS
import asyncio
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
async def main():
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
await acc.startup()
# send 5 USDC to azbang.near
tr = await acc.ft.transfer(FTS.USDC, "azbang.near", 5, force_register=True)
print(tr.transaction.hash)
asyncio.run(main())
Documentation
- class FT(DappClient)
Client to any NEP-141 contract` With this contract you can send fungible tokens to any user
acc = Account(...) ft = acc.ft await acc.ft.transfer(FTS.USDC, "azbang.near", 5, force_register=True)
- get_ft_balance(ft: FtModel, account_id: str)
Get fungible token balance
- Parameters:
ft – fungible token model FT.USDC
account_id – account id
- Returns:
amount // 10**ft.decimal
await acc.ft.get_ft_balance(FTS.USDC, account_id="azbang.near")
- get_metadata(ft: FtModel, account_id: str)
Get fungible token metadata
- Parameters:
ft – fungible token model FT.USDC
- Returns:
FtTokenMetadata
await acc.ft.get_metadata(FTS.USDC)
- transfer(ft: FtModel, account_id: str, amount: float, memo: str = '', force_register: bool = False)
Transfer fungible token to account
- Parameters:
ft – fungible token model FT.USDC
receiver_id – receiver account id
amount – float amount to transfer. 1 for 1 USDC
memo – comment
force_register – use storage_deposit() if account is not registered
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.ft.transfer(FTS.USDC, "azbang.near", 5, force_register=True)
- transfer_call(ft: FtModel, account_id: str, amount: float, memo: str = '', force_register: bool = False, nowait: bool = False)
Transfer fungible token to account and call ft_on_transfer() method in receiver contract
- Parameters:
ft – fungible token model FT.USDC
receiver_id – receiver account id
amount – float amount to transfer. 1 for 1 USDC
memo – comment
force_register – use storage_deposit() if account is not registered
nowait – if nowait is True, return transaction hash, else wait execution
- Returns:
transaction hash or TransactionResult
await acc.ft.transfer_call(FTS.USDC, "azbang.near", 5, force_register=True)
- storage_balance_of(ft: FtModel, account_id: str)
Get storage balance of account. The balance must be greater than 0.01 NEAR for some smart contracts in order for the recipient to accept the token
- Parameters:
contract_id – fungible token contract_id
account_id – account id
- Returns:
int balance in yoctoNEAR, 1_000_000_000_000_000_000_000_000 for 1 NEAR
await acc.ft.storage_balance_of(FTS.USDC, "azbang.near")
- storage_deposit(ft: FtModel, account_id: str, amount: int = NEAR // 50)
Deposit storage balance for account. The balance must be greater than 0.01 NEAR for some smart contracts
- Parameters:
ft – fungible token model FT.USDC
account_id – receiver account id
amount – in amount of yoctoNEAR
- Returns:
await acc.ft.storage_deposit(FTS.USDC, "azbang.near")
Staking
Note
Class to stake NEAR on liquid staking. You can stake NEAR and withdraw at any time without fees
Read more about staking: https://docs.herewallet.app/technology-description/readme
Quick start
from pynear.account import Account
from pynear.dapps.fts import FTS
import asyncio
ACCOUNT_ID = "bob.near"
PRIVATE_KEY = "ed25519:..."
async def main():
acc = Account(ACCOUNT_ID, PRIVATE_KEY)
await acc.startup()
transaction = await acc.staking.stake(10000)
print(tr.transaction.hash)
transaction = await acc.staking.receive_dividends()
print(tr.logs)
transaction = await acc.staking.unstake(10000)
print(tr.transaction.hash)
asyncio.run(main())
Documentation
- class Staking(DappClient)
Client to storage.herewallet.near contract With this contract you can stake NEAR without blocking and receive passive income ~9% APY
acc = Account(...) staking = acc.staking
- class StakingData(DappClient)
- apy_value: int
current APY value * 100 (908=9.08%)
- last_accrual_ts: int
Last UTC timestamp of accrued recalc
- accrued: int
Total accrued in yoctoNEAR, which can be receiver by receive_dividends() call
- transfer(account_id: str, amount: int, memo: str = '', force_register: bool = False)
Transfer hNEAR to account
- Parameters:
receiver_id – receiver account id
amount – amount in yoctoNEAR
memo – comment
:param nowait if True, method will return before transaction is confirmed :return: transaction hash ot TransactionResult
await acc.staking.transfer("azbang.near", 10000)
- transfer_call(account_id: str, amount: int, memo: str = '', force_register: bool = False)
Transfer hNEAR to account and call on_transfer_call() on receiver smart contract
- Parameters:
receiver_id – receiver account id
amount – amount in yoctoNEAR
memo – comment
:param nowait if True, method will return before transaction is confirmed :return: transaction hash ot TransactionResult
await acc.staking.transfer_call("azbang.near", 10000)
- get_staking_amount(account_id: str)
Get staking balance of account.
- Parameters:
account_id – account id
:param nowait if True, method will return before transaction is confirmed :return: int balance in yoctoNEAR
amount = await acc.staking.get_staking_amount("azbang.near") print(amount)
- get_user(account_id: str)
Get user staking parameters
- Parameters:
account_id – account id
- Returns:
StakingData
data = await acc.staking.get_user("azbang.near") print(data.apy_value / 100)
- stake(amount: int, nowait: bool = False)
Deposit staking for account
- Parameters:
amount – in amount of yoctoNEAR
nowait – if True, method will return before transaction is confirmed
- Returns:
transaction hash or TransactionResult
res = await acc.staking.stake(1_000_000_000_000_000) print(res.transaction.hash)
- unstake(amount: int, nowait: bool = False)
Withdraw from staking
- Parameters:
amount – in amount of yoctoNEAR
nowait – if True, method will return before transaction is confirmed
- Returns:
transaction hash or TransactionResult
res = await acc.staking.unstake(1_000_000_000_000_000) print(res.transaction.hash)
- receive_dividends(nowait: bool = False)
Receive dividends. user.accrued yoctoNEAR amount will transfer to staking balance
- Parameters:
nowait – if True, method will return before transaction is confirmed
- Returns:
transaction hash ot TransactionResult
res = await acc.staking.receive_dividends() print(res.transaction.hash)
Delegate Transactions
Description
NEAR Protocol supports delegate transactions since version 0.17.0 This is a special type of transaction which can be created and signed by one account but sent on behalf of another account. Delegate transactions used to pay for gas for a third party.
These transactions are performed in three steps.
Alice creates a
delegate_action
and specifies all the actions, public key and recipient.Alice signs
delegate_action
with her private key and gives it to Bob.Bob forms a normal transaction from one action -
delegate_action
, signs it and sends to the blockchain. In fact, the Alice transaction is executed, but the Bob pays for the gas.
Make delegate transaction with py_near
The following Python function creates and signs a delegate transaction.
Create a
DelegateActionModel
object with thecreate_delegate_action
method. This method takes the following parameters:actions
: A list ofAction
objects. In this example, we use aTransferAction
object.receiver_id
: The NEAR Protocol account ID where you want to send the transaction.
Sign the delegate transaction with the
sign_delegate_transaction
method. This method takes the following parameters:delegate_action
: TheDelegateActionModel
object you created in the previous step.private_key
: The private key of the NEAR Protocol account that you want to use to sign the transaction.
Execute the delegate transaction with the
call_delegate_transaction
method. This method takes the following parameters:delegate_action
: TheDelegateActionModel
object you created in the previous step.signature
: The signature of the delegate transaction that you created in the previous step.
You can execute this transaction from any NEAR Protocol account.
from py_near.account import Account
from py_near_primitives import TransferAction
import ed25519
async def f():
account = Account(
"alisa.near",
"ed25519::...",
"https://nrpc.herewallet.app",
)
action = await account.create_delegate_action(actions=[TransferAction(1)], receiver_id="illia.near")
sign = account.sign_delegate_transaction(action)
account_to_execute = Account(
"bob.near",
"ed25519:...",
"https://nrpc.herewallet.app",
)
res = account_to_execute acc.call_delegate_transaction(
delegate_action=action,
signature=sign,
)
In this example, we transfer 1 yNEAR from alisa.near
to illia.near
and pay for gas from bob.near
balance.
Note
Replace the ed25519
public and private keys in the Account
objects with your actual account keys.
You also need to replace the receiver_id
value in the create_delegate_action
method with the actual NEAR Protocol account ID where you want to send the transaction.
Warning
For now not all rpc support delegate transactions. You can use https://nrpc.herewallet.app
for testing.
Make delegate transaction manually
The following Python function creates and signs a delegate transaction from alisa.near
account.
from py_near.account import Account
from py_near_primitives import TransferAction
from py_near.models import DelegateActionModel
import ed25519
private_key = ed25519.SigningKey(base58.b58decode("...."))
public_key = base58.b58encode(private_key.get_verifying_key().to_bytes()).decode()
action = DelegateActionModel(
sender_id="alisa.near",
receiver_id="illia.near",
actions=[TransferAction(1)],
nonce=ALISA_KEY_NONCE + 1,
max_block_height=CURRENT_BLOCK_HEIGHT + 1,
public_key=public_key,
)
sign = private_key.sign(action.nep461_hash)
And now send this transaction and pay for gas from bob.near
balance.
from py_near.account import Account
account_to_execute = Account(
"bob.near",
"ed25519:...",
"https://nrpc.herewallet.app",
)
account_to_execute = await acc.call_delegate_transaction(
delegate_action=action,
signature=sign,
)