def test_find_program_address_ref(self, program_id, expected): """Test with addresses generated by rust impl """ pid = PublicKey.from_base58(program_id) exp = PublicKey.from_base58(expected) actual = find_program_address(pid, ['Lil\''.encode(), 'Bits'.encode()]) assert actual == exp
def test_get_associated_account(self): # Values generated from taken from spl code. wallet = PublicKey.from_base58( '4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM') mint = PublicKey.from_base58( '8opHzTAnfzRpPEx21XtnrVTX28YQuCpAjcn1PczScKh') expected = PublicKey.from_base58( 'H7MQwEzt97tUJryocn3qaEoy2ymWstwyEk1i9Yv3EmuZ') actual = get_associated_account(wallet, mint) assert actual == expected
from typing import NamedTuple from agora.keys import PublicKey from agora.solana.instruction import Instruction from agora.solana.transaction import Message # The address of the memo program that should be used. # todo: lock this in, or make configurable PROGRAM_KEY = PublicKey.from_base58( 'Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo') # Reference: https://github.com/solana-labs/solana-program-library/blob/master/memo/program/src/entrypoint.rs def memo_instruction(data: str) -> Instruction: return Instruction( PROGRAM_KEY, bytes(data, 'utf-8'), ) class DecompiledMemo(NamedTuple): data: bytes def decompile_memo(m: Message, index: int) -> DecompiledMemo: if index >= len(m.instructions): raise ValueError(f"instruction doesn't exist at {index}") i = m.instructions[index] if m.accounts[i.program_index] != PROGRAM_KEY:
ap = argparse.ArgumentParser() ap.add_argument('-s', '--sender', required=True, help='The private seed of the sender account') ap.add_argument('-d', '--destination', required=True, help='The public address of the destination account') args = vars(ap.parse_args()) client = Client(Environment.TEST, 1) # 1 is the test app index source = PrivateKey.from_base58(args['sender']) dest = PublicKey.from_base58(args['destination']) # Send a payment of 1 Kin payment = Payment(source, dest, TransactionType.EARN, kin_to_quarks('1')) try: tx_id = client.submit_payment(p) print( f'transaction successfully submitted with hash: {base58.b58encode(tx_id)}' ) except Error as e: print(f'transaction failed: {repr(e)}') if isinstance(e, TransactionErrors): print( f'tx_error={repr(e.tx_error)}, len(op_errors)={len(e.op_errors)}') for op_error in e.op_errors: print(f'op_error={repr(op_error)}')
# todo: lock in token program key and remove token_program parameters from enum import IntEnum from typing import NamedTuple, Optional from agora.keys import PublicKey, ED25519_PUB_KEY_SIZE from agora.solana.instruction import Instruction, AccountMeta from agora.solana.transaction import Message # Reference: https://github.com/solana-labs/solana-program-library/blob/11b1e3eefdd4e523768d63f7c70a7aa391ea0d02/token/program/src/state.rs#L125 # noqa: E501 ACCOUNT_SIZE = 165 # RentSysVar points to the system variable "Rent" # # Source: https://github.com/solana-labs/solana/blob/f02a78d8fff2dd7297dc6ce6eb5a68a3002f5359/sdk/src/sysvar/rent.rs#L11 _RENT_SYS_VAR = PublicKey.from_base58('SysvarRent111111111111111111111111111111111') class Command(IntEnum): INITIALIZE_MINT = 0 INITIALIZE_ACCOUNT = 1 INITIALIZE_MULTISIG = 2 TRANSFER = 3 APPROVE = 4 REVOKE = 5 SET_AUTHORITY = 6 MINT_TO = 7 BURN = 8 CLOSE_ACCOUNT = 9 FREEZE_ACCOUNT = 10 THAW_ACCOUNT = 11 TRANSFER_2 = 12
# todo: lock in token program key and remove token_program parameters from enum import IntEnum from typing import NamedTuple, Optional from agora.keys import PublicKey, ED25519_PUB_KEY_SIZE from agora.solana import system from agora.solana.instruction import Instruction, AccountMeta from agora.solana.transaction import Message # Reference: https://github.com/solana-labs/solana-program-library/blob/11b1e3eefdd4e523768d63f7c70a7aa391ea0d02/token/program/src/state.rs#L125 # noqa: E501 ACCOUNT_SIZE = 165 PROGRAM_KEY = PublicKey.from_base58( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") class Command(IntEnum): INITIALIZE_MINT = 0 INITIALIZE_ACCOUNT = 1 INITIALIZE_MULTISIG = 2 TRANSFER = 3 APPROVE = 4 REVOKE = 5 SET_AUTHORITY = 6 MINT_TO = 7 BURN = 8 CLOSE_ACCOUNT = 9 FREEZE_ACCOUNT = 10 THAW_ACCOUNT = 11 TRANSFER_2 = 12 APPROVE_2 = 13
from agora.keys import PrivateKey, PublicKey from agora.model import Earn, Invoice, LineItem from agora.model.earn import EarnBatch from agora.utils import kin_to_quarks ap = argparse.ArgumentParser() ap.add_argument('-s', '--sender', required=True, help='The base58-encoded private seed of the sender account') ap.add_argument('-d', '--destinations', required=True, help='A comma-delimited list of base58-encoded account addresses to send earns to ' '(e.g. add1,addr2,add3)') args = vars(ap.parse_args()) client = Client(Environment.TEST, 1) # 1 is the test app index source = PrivateKey.from_base58(args['sender']) destinations = [PublicKey.from_base58(addr) for addr in args['destinations'].split(',')] # Send an earn batch with 1 Kin each earns = [Earn(dest, kin_to_quarks('1')) for idx, dest in enumerate(destinations)] batch_result = client.submit_earn_batch(EarnBatch(source, earns)) if batch_result.tx_error: print(f'{batch_result.tx_id} failed with error {repr(batch_result.tx_error)}') if batch_result.earn_errors: for e in batch_result.earn_errors: print(f'earn {e.earn_index} failed with error {repr(e.error)}') else: print(f'{batch_result.tx_id} submitted') # Send an earn batch of earns with 1 Kin each, with invoices earns = [Earn(dest, kin_to_quarks('1'), invoice=Invoice([LineItem(f'Payment {idx}', kin_to_quarks('1'))]))
from typing import List import base58 import pytest from agora.keys import PublicKey, PrivateKey from agora.solana.address import create_program_address, MAX_SEED_LENGTH, InvalidPublicKeyError, find_program_address _PROGRAM_ID = PublicKey.from_base58( 'BPFLoader1111111111111111111111111111111111') # The typo here was taken directly from the Solana test case, # which was used to derive the expected outputs. _PUBLIC_KEY = base58.b58decode('SeedPubey1111111111111111111111111111111111') class TestCreateProgramAddress: def test_create_program_address_max_seed_length(self): max_seed = bytes(MAX_SEED_LENGTH) exceeded_seed = bytes(MAX_SEED_LENGTH + 1) with pytest.raises(ValueError): create_program_address(_PROGRAM_ID, [exceeded_seed]) with pytest.raises(ValueError): create_program_address(_PROGRAM_ID, ['short seed'.encode(), exceeded_seed]) assert create_program_address(_PROGRAM_ID, [max_seed]) @pytest.mark.parametrize('expected, seeds', [ ('3gF2KMe9KiC6FNVBmfg9i267aMPvK37FewCip4eGBFcT', [bytes(),
from typing import NamedTuple, Tuple from agora.keys import PublicKey from agora.solana import system from agora.solana.address import find_program_address from agora.solana.instruction import Instruction, AccountMeta from agora.solana.transaction import Message from .program import PROGRAM_KEY ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_KEY = PublicKey.from_base58( 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL') def get_associated_account(wallet: PublicKey, mint: PublicKey) -> PublicKey: return find_program_address( ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_KEY, [ wallet.raw, PROGRAM_KEY.raw, mint.raw, ], ) def create_associated_token_account( subsidizer: PublicKey, wallet: PublicKey, mint: PublicKey, ) -> Tuple[Instruction, PublicKey]: addr = get_associated_account(wallet, mint) return Instruction(
try: client.create_account(sender) print('account created') except AccountExistsError: print(f'account {sender_addr} already exists') print(f'balance: {client.get_balance(sender.public_key)}') print(f'requesting airdrop for {sender_addr}') airdrop_resp = client._internal_client.request_airdrop(sender.public_key, int(3e5)) print(f'funded {sender_addr}') # use airdrop source as destination for the following transactions airdrop_source = PublicKey.from_base58("DemXVWQ9DXYsGFpmjFXxki3PE1i3VoHQtqxXQFx38pmU") # Send a payment of 1 Kin tx_id = submit_payment(Payment(sender, airdrop_source, TransactionType.NONE, int(1e5))) print(f'submitted: {base58.b58encode(tx_id)}') tx_data = client.get_transaction(tx_id) print(repr(tx_data)) # Send a payment of 1 Kin with a text memo tx_id = submit_payment(Payment(sender, airdrop_source, TransactionType.NONE, int(1e5), memo='somememo')) print(f'submitted: {base58.b58encode(tx_id)}') tx_data = client.get_transaction(tx_id) print(repr(tx_data))