示例#1
0
    def msg_deployed(self, message):
        print('msg_deployed method of the solana spl token')
        if self.contract.state != 'WAITING_FOR_DEPLOYMENT':
            take_off_blocking(self.contract.network.name)
            return
        else:
            conn = SolanaInt(self.contract.network.name).connect()
            key = Keypair.from_secret_key(bytes(SOLANA_KEYPAIR[0:32]))
            token_address = PublicKey(self.solana_contract.address)
            tok_int = Token(conn, token_address, TOKEN_PROGRAM_ID, key)
            holders = self.contract.tokenholder_set.all()
            if holders:
                print('transfering premint tokens')
                for th in holders:
                    holder_addr = PublicKey(th.address)
                    try:
                        associated_address = tok_int.create_associated_token_account(holder_addr)
                        print(f'created associated account {associated_address}')
                    except RPCException:
                        print('associated token account already created')
                        associated_address = get_associated_token_address(holder_addr, tok_int.pubkey)
                    response = tok_int.mint_to(associated_address, key, int(th.amount))
                    print(f'tx_hash = {response["result"]}')

            print('transferring of mint authority started')
            owner = PublicKey(self.admin_address)
            address = self.solana_contract.address
            tok_int.set_authority(address, key.public_key, 0, owner)
            print('successfully transferred mint authority')

            self.initialized({})
示例#2
0
    def sol_instr_partial_call_or_continue(self, storage_account, step_count, evm_instruction):
        return TransactionInstruction(
            program_id=self.loader.loader_id,
            data=bytearray.fromhex("0D") + self.collateral_pool_index_buf + step_count.to_bytes(8, byteorder='little') + evm_instruction,
            keys=[
                AccountMeta(pubkey=storage_account, is_signer=False, is_writable=True),

                # System instructions account:
                AccountMeta(pubkey=PublicKey(SYSVAR_INSTRUCTION_PUBKEY), is_signer=False, is_writable=False),
                # Operator address:
                AccountMeta(pubkey=self.acc.public_key(), is_signer=True, is_writable=True),
                # Collateral pool address:
                AccountMeta(pubkey=self.collateral_pool_address, is_signer=False, is_writable=True),
                # Operator's NEON token account:
                AccountMeta(pubkey=get_associated_token_address(self.acc.public_key(), ETH_TOKEN_MINT_ID), is_signer=False, is_writable=True),
                # User's NEON token account:
                AccountMeta(pubkey=self.caller_token, is_signer=False, is_writable=True),
                # System program account:
                AccountMeta(pubkey=PublicKey(SYS_PROGRAM_ID), is_signer=False, is_writable=False),

                AccountMeta(pubkey=self.reId, is_signer=False, is_writable=True),
                AccountMeta(pubkey=self.re_code, is_signer=False, is_writable=True),
                AccountMeta(pubkey=self.caller, is_signer=False, is_writable=True),
                AccountMeta(pubkey=self.caller_token, is_signer=False, is_writable=True),

                AccountMeta(pubkey=self.loader.loader_id, is_signer=False, is_writable=False),
                AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False),
                AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
            ])
示例#3
0
 def create_account_instruction(self, eth_address: str, payer: PublicKey):
     dest_address_solana, nonce = get_evm_loader_account_address(
         eth_address)
     neon_token_account = get_associated_token_address(
         dest_address_solana, ETH_TOKEN_MINT_ID)
     return TransactionInstruction(
         program_id=EVM_LOADER_ID,
         data=create_account_layout(0, 0, bytes.fromhex(eth_address[2:]),
                                    nonce),
         keys=[
             AccountMeta(pubkey=payer, is_signer=True, is_writable=True),
             AccountMeta(pubkey=dest_address_solana,
                         is_signer=False,
                         is_writable=True),
             AccountMeta(pubkey=neon_token_account,
                         is_signer=False,
                         is_writable=True),
             AccountMeta(pubkey=SYS_PROGRAM_ID,
                         is_signer=False,
                         is_writable=False),
             AccountMeta(pubkey=ETH_TOKEN_MINT_ID,
                         is_signer=False,
                         is_writable=False),
             AccountMeta(pubkey=TOKEN_PROGRAM_ID,
                         is_signer=False,
                         is_writable=False),
             AccountMeta(pubkey=ASSOCIATED_TOKEN_PROGRAM_ID,
                         is_signer=False,
                         is_writable=False),
             AccountMeta(pubkey=SYSVAR_RENT_PUBKEY,
                         is_signer=False,
                         is_writable=False),
         ])
示例#4
0
 def mint_to(self,
             api_endpoint,
             pool_account,
             dest,
             amount,
             skip_confirmation=True):
     msg = ""
     client = Client(api_endpoint)
     msg += "Initialized client"
     # Create account objects
     source_account = Account(self.private_key)
     signers = [source_account]
     pool = self.load_binary_option(api_endpoint, pool_account)
     # List non-derived accounts
     pool_account = PublicKey(pool_account)
     dest_account = PublicKey(dest)
     escrow_mint_account = PublicKey(pool["escrow_mint"])
     mint_authority_account = source_account.public_key()
     payer_account = source_account.public_key()
     token_account = PublicKey(TOKEN_PROGRAM_ID)
     tx = Transaction()
     token_pda_address = get_associated_token_address(
         dest_account, escrow_mint_account)
     associated_token_account_ix = create_associated_token_account(
         payer=payer_account,
         owner=dest_account,
         mint=escrow_mint_account,
     )
     tx = tx.add(associated_token_account_ix)
     mint_to_ix = mint_to(
         MintToParams(
             program_id=token_account,
             mint=escrow_mint_account,
             dest=token_pda_address,
             mint_authority=mint_authority_account,
             amount=int(amount),
             signers=[mint_authority_account],
         ))
     tx = tx.add(mint_to_ix)
     # Send request
     try:
         response = client.send_transaction(
             tx,
             *signers,
             opts=types.TxOpts(skip_confirmation=skip_confirmation))
         return json.dumps({
             'status':
             HTTPStatus.OK,
             'msg':
             msg + f" | MintTo {dest} successful",
             'tx':
             response.get('result') if skip_confirmation else
             response['result']['transaction']['signatures'],
         })
     except Exception as e:
         msg += f" | ERROR: Encountered exception while attempting to send transaction: {e}"
         raise (e)
示例#5
0
 def __init__(self):
     # Initialize user account
     self.signer = get_solana_accounts()[0]
     self.solana = SolanaInteractor(SOLANA_URL)
     self.waiter = None
     self._operator = self.signer.public_key()
     self.operator_token = get_associated_token_address(
         PublicKey(self._operator), ETH_TOKEN_MINT_ID)
     self.builder = NeonInstruction(self._operator)
示例#6
0
    def get_accounts(self, ether):
        (sol_address, _) = self.loader.ether2program(ether)
        info = client.get_account_info(sol_address, commitment=Confirmed)['result']['value']
        data = base64.b64decode(info['data'][0])
        acc_info = ACCOUNT_INFO_LAYOUT.parse(data)

        code_address = PublicKey(acc_info.code_account)
        alternate_token = get_associated_token_address(PublicKey(sol_address), ETH_TOKEN_MINT_ID)

        return (sol_address, alternate_token, code_address)
示例#7
0
async def test_deposit_withdraw_sol(async_client, payer):
    fee = Fee(numerator=1, denominator=1000)
    referral_fee = 20
    (stake_pool_address, validator_list_address) = await create_all(async_client, payer, fee, referral_fee)
    resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed)
    data = resp['result']['value']['data']
    stake_pool = StakePool.decode(data[0], data[1])
    token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint)
    deposit_amount = 100_000_000
    await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount)
    pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed)
    assert pool_token_balance['result']['value']['amount'] == str(deposit_amount)
    recipient = Keypair()
    await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.public_key, deposit_amount)
    pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed)
    assert pool_token_balance['result']['value']['amount'] == str('0')
示例#8
0
async def test_deposit_withdraw_stake(async_client, validators, payer,
                                      stake_pool_addresses, waiter):
    (stake_pool_address, validator_list_address) = stake_pool_addresses
    resp = await async_client.get_account_info(stake_pool_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    stake_pool = StakePool.decode(data[0], data[1])
    validator = next(iter(validators))
    stake_amount = 1_000_000
    stake = Keypair()
    await create_stake(async_client, payer, stake, payer.public_key,
                       stake_amount)
    stake = stake.public_key
    await delegate_stake(async_client, payer, payer, stake, validator)
    resp = await async_client.get_account_info(stake, commitment=Confirmed)
    data = resp['result']['value']['data']
    stake_state = StakeState.decode(data[0], data[1])
    print(stake_state)

    await waiter.wait_for_next_epoch(async_client)

    await update_stake_pool(async_client, payer, stake_pool_address)
    token_account = get_associated_token_address(payer.public_key,
                                                 stake_pool.pool_mint)
    await deposit_stake(async_client, payer, stake_pool_address, validator,
                        stake, token_account)
    pool_token_balance = await async_client.get_token_account_balance(
        token_account, Confirmed)
    pool_token_balance = pool_token_balance['result']['value']['amount']
    resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN)
    stake_rent_exemption = resp['result']
    assert pool_token_balance == str(stake_amount + stake_rent_exemption)

    destination_stake = Keypair()
    await withdraw_stake(async_client, payer, payer, destination_stake,
                         stake_pool_address, validator, payer.public_key,
                         token_account, stake_amount)

    pool_token_balance = await async_client.get_token_account_balance(
        token_account, Confirmed)
    pool_token_balance = pool_token_balance['result']['value']['amount']
    assert pool_token_balance == str(stake_rent_exemption)
示例#9
0
async def test_rebalance_this_is_very_slow(async_client, validators, payer,
                                           stake_pool_addresses, waiter):
    (stake_pool_address, validator_list_address) = stake_pool_addresses
    resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN)
    stake_rent_exemption = resp['result']
    increase_amount = 100_000_000
    deposit_amount = (increase_amount + stake_rent_exemption) * len(validators)

    resp = await async_client.get_account_info(stake_pool_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    stake_pool = StakePool.decode(data[0], data[1])
    token_account = get_associated_token_address(payer.public_key,
                                                 stake_pool.pool_mint)
    await deposit_sol(async_client, payer, stake_pool_address, token_account,
                      deposit_amount)

    # Test case 1: Increase
    await rebalance(ENDPOINT, stake_pool_address, payer, 0.0)

    # should only have minimum left
    resp = await async_client.get_account_info(stake_pool.reserve_stake,
                                               commitment=Confirmed)
    assert resp['result']['value']['lamports'] == stake_rent_exemption + 1

    # should all be the same
    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.active_stake_lamports == 0
        assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption

    # Test case 2: Decrease
    print('Waiting for next epoch')
    await waiter.wait_for_next_epoch(async_client)
    await rebalance(ENDPOINT, stake_pool_address, payer,
                    deposit_amount / 1_000_000_000)

    # should still only have minimum left + rent exemptions from increase
    resp = await async_client.get_account_info(stake_pool.reserve_stake,
                                               commitment=Confirmed)
    reserve_lamports = resp['result']['value']['lamports']
    assert reserve_lamports == stake_rent_exemption * (
        1 + len(validator_list.validators)) + 1

    # should all be decreasing now
    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.active_stake_lamports == 0
        assert validator.transient_stake_lamports == increase_amount

    # Test case 3: Do nothing
    print('Waiting for next epoch')
    await waiter.wait_for_next_epoch(async_client)
    await rebalance(ENDPOINT, stake_pool_address, payer,
                    deposit_amount / 1_000_000_000)

    # should still only have minimum left + rent exemptions from increase
    resp = await async_client.get_account_info(stake_pool.reserve_stake,
                                               commitment=Confirmed)
    reserve_lamports = resp['result']['value']['lamports']
    assert reserve_lamports == stake_rent_exemption + deposit_amount + 1

    # should all be decreasing now
    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.active_stake_lamports == 0
        assert validator.transient_stake_lamports == 0
示例#10
0
 def collect(self,
             api_endpoint,
             pool_account,
             collector,
             skip_confirmation=True):
     msg = ""
     client = Client(api_endpoint)
     msg += "Initialized client"
     signers = [Account(self.private_key)]
     pool = self.load_binary_option(api_endpoint, pool_account)
     pool_account = PublicKey(pool_account)
     collector_account = PublicKey(collector)
     escrow_account = PublicKey(pool["escrow"])
     escrow_mint_account = PublicKey(pool["escrow_mint"])
     long_token_mint_account = PublicKey(pool["long_mint"])
     short_token_mint_account = PublicKey(pool["short_mint"])
     token_account = PublicKey(TOKEN_PROGRAM_ID)
     escrow_authority_account = PublicKey.find_program_address(
         [
             bytes(long_token_mint_account),
             bytes(short_token_mint_account),
             bytes(token_account),
             bytes(PublicKey(BINARY_OPTION_PROGRAM_ID))
         ],
         PublicKey(BINARY_OPTION_PROGRAM_ID),
     )[0]
     # Transaction
     tx = Transaction()
     atas = []
     for mint_account in (long_token_mint_account, short_token_mint_account,
                          escrow_mint_account):
         token_pda_address = get_associated_token_address(
             collector_account, mint_account)
         associated_token_account_info = client.get_account_info(
             token_pda_address)
         account_info = associated_token_account_info['result']['value']
         if account_info is not None:
             account_state = ACCOUNT_LAYOUT.parse(
                 base64.b64decode(account_info['data'][0])).state
         else:
             account_state = 0
         if account_state == 0:
             msg += f" | Error Fetching PDA: {token_pda_address}"
             raise Exception()
         else:
             msg += f" | Fetched PDA: {token_pda_address}"
         atas.append(token_pda_address)
     collect_ix = collect_instruction(
         pool_account,
         collector_account,
         atas[0],
         atas[1],
         atas[2],
         long_token_mint_account,
         short_token_mint_account,
         escrow_account,
         escrow_authority_account,
         token_account,
     )
     tx = tx.add(collect_ix)
     try:
         response = client.send_transaction(
             tx,
             *signers,
             opts=types.TxOpts(skip_confirmation=skip_confirmation))
         return json.dumps({
             'status':
             HTTPStatus.OK,
             'msg':
             msg + f" | Collect successful",
             'tx':
             response.get('result') if skip_confirmation else
             response['result']['transaction']['signatures'],
         })
     except Exception as e:
         msg += f" | ERROR: Encountered exception while attempting to send transaction: {e}"
         print(msg)
         raise (e)
示例#11
0
 def trade(self,
           api_endpoint,
           pool_account,
           buyer_encrypted_private_key,
           seller_encrypted_private_key,
           size,
           buyer_price,
           seller_price,
           skip_confirmation=True):
     msg = ""
     client = Client(api_endpoint)
     msg += "Initialized client"
     # Create account objects
     buyer_private_key = list(
         self.cipher.decrypt(buyer_encrypted_private_key))
     seller_private_key = list(
         self.cipher.decrypt(seller_encrypted_private_key))
     assert (len(buyer_private_key) == 32)
     assert (len(seller_private_key) == 32)
     source_account = Account(self.private_key)
     buyer = Account(buyer_private_key)
     seller = Account(seller_private_key)
     # Signers
     signers = [buyer, seller, source_account]
     pool = self.load_binary_option(api_endpoint, pool_account)
     # List non-derived accounts
     pool_account = PublicKey(pool_account)
     escrow_account = PublicKey(pool["escrow"])
     escrow_mint_account = PublicKey(pool["escrow_mint"])
     long_token_mint_account = PublicKey(pool["long_mint"])
     short_token_mint_account = PublicKey(pool["short_mint"])
     buyer_account = buyer.public_key()
     seller_account = seller.public_key()
     token_account = PublicKey(TOKEN_PROGRAM_ID)
     escrow_owner_account = PublicKey.find_program_address(
         [
             bytes(long_token_mint_account),
             bytes(short_token_mint_account),
             bytes(token_account),
             bytes(PublicKey(BINARY_OPTION_PROGRAM_ID))
         ],
         PublicKey(BINARY_OPTION_PROGRAM_ID),
     )[0]
     # Transaction
     tx = Transaction()
     atas = []
     for acct in [buyer_account, seller_account]:
         acct_atas = []
         for mint_account in (long_token_mint_account,
                              short_token_mint_account,
                              escrow_mint_account):
             token_pda_address = get_associated_token_address(
                 acct, mint_account)
             associated_token_account_info = client.get_account_info(
                 token_pda_address)
             account_info = associated_token_account_info['result']['value']
             if account_info is not None:
                 account_state = ACCOUNT_LAYOUT.parse(
                     base64.b64decode(account_info['data'][0])).state
             else:
                 account_state = 0
             if account_state == 0:
                 msg += f" | Creating PDA: {token_pda_address}"
                 associated_token_account_ix = create_associated_token_account(
                     payer=source_account.public_key(),
                     owner=acct,
                     mint=mint_account,
                 )
                 tx = tx.add(associated_token_account_ix)
             else:
                 msg += f" | Fetched PDA: {token_pda_address}"
             acct_atas.append(token_pda_address)
         atas.append(acct_atas)
     trade_ix = trade_instruction(
         pool_account,
         escrow_account,
         long_token_mint_account,
         short_token_mint_account,
         buyer_account,
         seller_account,
         atas[0][2],
         atas[1][2],
         atas[0][0],
         atas[0][1],
         atas[1][0],
         atas[1][1],
         escrow_owner_account,
         token_account,
         int(size),
         int(buyer_price),
         int(seller_price),
     )
     tx = tx.add(trade_ix)
     # Send request
     try:
         response = client.send_transaction(
             tx,
             *signers,
             opts=types.TxOpts(skip_confirmation=skip_confirmation))
         return json.dumps({
             'status':
             HTTPStatus.OK,
             'msg':
             msg + f" | Trade successful",
             'tx':
             response.get('result') if skip_confirmation else
             response['result']['transaction']['signatures'],
         })
     except Exception as e:
         msg += f" | ERROR: Encountered exception while attempting to send transaction: {e}"
         raise (e)
示例#12
0
def getTokenAddr(account):
    return get_associated_token_address(PublicKey(account), ETH_TOKEN_MINT_ID)
示例#13
0
async def test_increase_decrease_this_is_very_slow(async_client, validators,
                                                   payer, stake_pool_addresses,
                                                   waiter):
    (stake_pool_address, validator_list_address) = stake_pool_addresses
    resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN)
    stake_rent_exemption = resp['result']
    increase_amount = 100_000_000
    decrease_amount = increase_amount // 2
    deposit_amount = (increase_amount + stake_rent_exemption) * len(validators)

    resp = await async_client.get_account_info(stake_pool_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    stake_pool = StakePool.decode(data[0], data[1])
    token_account = get_associated_token_address(payer.public_key,
                                                 stake_pool.pool_mint)
    await deposit_sol(async_client, payer, stake_pool_address, token_account,
                      deposit_amount)

    # increase to all
    futures = [
        increase_validator_stake(async_client, payer, payer,
                                 stake_pool_address, validator,
                                 increase_amount) for validator in validators
    ]
    await asyncio.gather(*futures)

    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption
        assert validator.active_stake_lamports == 0

    print("Waiting for epoch to roll over")
    await waiter.wait_for_next_epoch(async_client)
    await update_stake_pool(async_client, payer, stake_pool_address)

    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.last_update_epoch != 0
        assert validator.transient_stake_lamports == 0
        assert validator.active_stake_lamports == increase_amount  # rent exemption brought back to reserve

    # decrease from all
    futures = [
        decrease_validator_stake(async_client, payer, payer,
                                 stake_pool_address, validator,
                                 decrease_amount) for validator in validators
    ]
    await asyncio.gather(*futures)

    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.transient_stake_lamports == decrease_amount
        assert validator.active_stake_lamports == increase_amount - decrease_amount

    print("Waiting for epoch to roll over")
    await waiter.wait_for_next_epoch(async_client)
    await update_stake_pool(async_client, payer, stake_pool_address)

    resp = await async_client.get_account_info(validator_list_address,
                                               commitment=Confirmed)
    data = resp['result']['value']['data']
    validator_list = ValidatorList.decode(data[0], data[1])
    for validator in validator_list.validators:
        assert validator.transient_stake_lamports == 0
        assert validator.active_stake_lamports == increase_amount - decrease_amount
示例#14
0
 def get_token_account_address(self, ether_addr: Union[str,
                                                       EthereumAddress]):
     sol_addr = PublicKey(ether2program(ether_addr)[0])
     return get_associated_token_address(sol_addr, self.token_mint)