示例#1
0
async def test_token(alt_stubbed_sender, test_http_client_async) -> AsyncToken:
    """Test create mint."""
    resp = await test_http_client_async.request_airdrop(alt_stubbed_sender.public_key(), AIRDROP_AMOUNT)
    confirmed = await aconfirm_transaction(test_http_client_async, resp["result"])
    assert_valid_response(confirmed)

    expected_decimals = 6
    expected_freeze_authority = Account()
    token_client = await AsyncToken.create_mint(
        test_http_client_async,
        alt_stubbed_sender,
        alt_stubbed_sender.public_key(),
        expected_decimals,
        TOKEN_PROGRAM_ID,
        expected_freeze_authority.public_key(),
    )

    assert token_client.pubkey
    assert token_client.program_id == TOKEN_PROGRAM_ID
    assert token_client.payer.public_key() == alt_stubbed_sender.public_key()

    resp = await test_http_client_async.get_account_info(token_client.pubkey)
    assert_valid_response(resp)
    assert resp["result"]["value"]["owner"] == str(TOKEN_PROGRAM_ID)

    mint_data = layouts.MINT_LAYOUT.parse(decode_byte_string(resp["result"]["value"]["data"][0]))
    assert mint_data.is_initialized
    assert mint_data.decimals == expected_decimals
    assert mint_data.supply == 0
    assert PublicKey(mint_data.mint_authority) == alt_stubbed_sender.public_key()
    assert PublicKey(mint_data.freeze_authority) == expected_freeze_authority.public_key()
    return token_client
示例#2
0
    def _create_account_args(
        self,
        owner: PublicKey,
        skip_confirmation: bool,
        balance_needed: int,
    ) -> Tuple[PublicKey, Transaction, Account, Account, TxOpts]:
        new_account = Account()
        # Allocate memory for the account

        # Construct transaction
        txn = Transaction()
        txn.add(
            sp.create_account(
                sp.CreateAccountParams(
                    from_pubkey=self.payer.public_key(),
                    new_account_pubkey=new_account.public_key(),
                    lamports=balance_needed,
                    space=ACCOUNT_LAYOUT.sizeof(),
                    program_id=self.program_id,
                )))
        txn.add(
            spl_token.initialize_account(
                spl_token.InitializeAccountParams(
                    account=new_account.public_key(),
                    mint=self.pubkey,
                    owner=owner,
                    program_id=self.program_id)))
        return (
            new_account.public_key(),
            txn,
            self.payer,
            new_account,
            TxOpts(skip_preflight=True, skip_confirmation=skip_confirmation),
        )
    def test_erc20_approveSolana(self):
        delegate = SolanaAccount()
        approve_value = 1000
        erc20 = self.wrapper.erc20_interface()

        nonce = proxy.eth.get_transaction_count(admin.address)
        tx = erc20.functions.approveSolana(bytes(delegate.public_key()),
                                           approve_value).buildTransaction(
                                               {'nonce': nonce})
        tx = proxy.eth.account.sign_transaction(tx, admin.key)
        tx_hash = proxy.eth.send_raw_transaction(tx.rawTransaction)
        tx_receipt = proxy.eth.wait_for_transaction_receipt(tx_hash)
        self.assertEqual(tx_receipt.status, 1)

        self.assertIsNotNone(tx_receipt)
        accounts = self.solana_client.get_token_accounts_by_delegate(
            delegate.public_key(),
            TokenAccountOpts(mint=self.token.pubkey),
            commitment=Recent)
        accounts = list(
            map(lambda a: PublicKey(a['pubkey']), accounts['result']['value']))

        self.assertIn(
            self.wrapper.get_neon_erc20_account_address(admin.address),
            accounts)
示例#4
0
def test_account_keypair():
    """Validate account keypair against account's private and public key."""
    expected_account = Account()
    keypair = expected_account.keypair()
    decoded_keypair = b58decode(keypair)

    actual_account = Account(decoded_keypair[:32])
    assert expected_account.public_key() == actual_account.public_key()
    assert expected_account.secret_key() == actual_account.secret_key()
示例#5
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)
示例#6
0
    def create_mint(
        conn: Client,
        payer: Account,
        mint_authority: PublicKey,
        decimals: int,
        program_id: PublicKey,
        freeze_authority: Optional[PublicKey] = None,
        skip_confirmation: bool = False,
    ) -> Token:
        """Create and initialize a token.

        :param conn: RPC connection to a solana cluster.
        :param payer: Fee payer for transaction.
        :param mint_authority: Account or multisig that will control minting.
        :param decimals: Location of the decimal place.
        :param program_id: SPL Token program account.
        :param freeze_authority: (optional) Account or multisig that can freeze token accounts.
        :param skip_confirmation: (optional) Option to skip transaction confirmation.
        :return: Token object for the newly minted token.

        If skip confirmation is set to `False`, this method will block for at most 30 seconds
        or until the transaction is confirmed.
        """
        mint_account = Account()
        token = Token(conn, mint_account.public_key(), program_id, payer)
        # Allocate memory for the account
        balance_needed = Token.get_min_balance_rent_for_exempt_for_mint(conn)
        # Construct transaction
        txn = Transaction()
        txn.add(
            sp.create_account(
                sp.CreateAccountParams(
                    from_pubkey=payer.public_key(),
                    new_account_pubkey=mint_account.public_key(),
                    lamports=balance_needed,
                    space=MINT_LAYOUT.sizeof(),
                    program_id=program_id,
                )
            )
        )
        txn.add(
            spl_token.initialize_mint(
                spl_token.InitializeMintParams(
                    program_id=program_id,
                    mint=mint_account.public_key(),
                    decimals=decimals,
                    mint_authority=mint_authority,
                    freeze_authority=freeze_authority,
                )
            )
        )
        # Send the two instructions
        conn.send_transaction(
            txn, payer, mint_account, opts=TxOpts(skip_confirmation=skip_confirmation, skip_preflight=True)
        )
        return token
示例#7
0
def test_dedup_signatures(stubbed_blockhash):
    """Test signature deduplication."""
    acc1, acc2 = Account(), Account()
    transfer1 = sp.transfer(
        sp.TransferParams(from_pubkey=acc1.public_key(),
                          to_pubkey=acc2.public_key(),
                          lamports=123))
    transfer2 = sp.transfer(
        sp.TransferParams(from_pubkey=acc1.public_key(),
                          to_pubkey=acc2.public_key(),
                          lamports=123))
    txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(
        transfer1, transfer2)
    txn.sign(acc1)
示例#8
0
 def cancel_order(self,
                  owner: Account,
                  order: t.Order,
                  opts: TxOpts = TxOpts()) -> RPCResponse:
     txn = Transaction().add(
         self.make_cancel_order_instruction(owner.public_key(), order))
     return self._conn.send_transaction(txn, owner, opts=opts)
示例#9
0
 def make_place_order_instruction(  # pylint: disable=too-many-arguments
     self,
     payer: PublicKey,
     owner: Account,
     order_type: OrderType,
     side: Side,
     limit_price: int,
     max_quantity: int,
     client_id: int,
     open_order_account: PublicKey,
 ) -> TransactionInstruction:
     if self.state.base_size_number_to_lots(max_quantity) < 0:
         raise Exception("Size lot %d is too small" % max_quantity)
     if self.state.price_number_to_lots(limit_price) < 0:
         raise Exception("Price lot %d is too small" % limit_price)
     return instructions.new_order(
         instructions.NewOrderParams(
             market=self.state.public_key(),
             open_orders=open_order_account,
             payer=payer,
             owner=owner.public_key(),
             request_queue=self.state.request_queue(),
             base_vault=self.state.base_vault(),
             quote_vault=self.state.quote_vault(),
             side=side,
             limit_price=limit_price,
             max_quantity=max_quantity,
             order_type=order_type,
             client_id=client_id,
             program_id=self.state.program_id(),
         ))
示例#10
0
class Wallet:
    def __init__(self, secret_key):
        self.logger: logging.Logger = logging.getLogger(
            self.__class__.__name__)
        self.secret_key = secret_key[0:32]
        self.account = Account(self.secret_key)

    @property
    def address(self) -> PublicKey:
        return self.account.public_key()

    def save(self, filename: str, overwrite: bool = False) -> None:
        if os.path.isfile(filename) and not overwrite:
            raise Exception(f"Wallet file '{filename}' already exists.")

        with open(filename, "w") as json_file:
            json.dump(list(self.secret_key), json_file)

    @staticmethod
    def load(filename: str = _DEFAULT_WALLET_FILENAME) -> "Wallet":
        if not os.path.isfile(filename):
            logging.error(f"Wallet file '{filename}' is not present.")
            raise Exception(f"Wallet file '{filename}' is not present.")
        else:
            with open(filename) as json_file:
                data = json.load(json_file)
                return Wallet(data)

    @staticmethod
    def create() -> "Wallet":
        new_account = Account()
        new_secret_key = new_account.secret_key()
        return Wallet(new_secret_key)
示例#11
0
 def topup(self, api_endpoint, to, amount=None, skip_confirmation=True):
     """
     Send a small amount of native currency to the specified wallet to handle gas fees. Return a status flag of success or fail and the native transaction data.
     """
     msg = ""
     try:
         # Connect to the api_endpoint
         client = Client(api_endpoint)
         msg += "Initialized client"
         # List accounts
         sender_account = Account(self.private_key)
         dest_account = PublicKey(to)
         msg += " | Gathered accounts"
         # List signers
         signers = [sender_account]
         # Start transaction
         tx = Transaction()
         # Determine the amount to send
         try:
             if amount is None:
                 min_rent_reseponse = client.get_minimum_balance_for_rent_exemption(
                     ACCOUNT_LAYOUT.sizeof())
                 lamports = min_rent_reseponse["result"]
             else:
                 lamports = int(amount)
             msg += f" | Fetched lamports: {lamports * 1e-9} SOL"
         except Exception as e:
             msg += " | ERROR: couldn't process lamports"
             raise (e)
         # Generate transaction
         transfer_ix = transfer(
             TransferParams(from_pubkey=sender_account.public_key(),
                            to_pubkey=dest_account,
                            lamports=lamports))
         tx = tx.add(transfer_ix)
         msg += f" | Transferring funds"
         # Send request
         try:
             response = client.send_transaction(
                 tx,
                 *signers,
                 opts=types.TxOpts(skip_confirmation=skip_confirmation))
             return json.dumps({
                 'status':
                 HTTPStatus.OK,
                 'msg':
                 f"Successfully sent {lamports * 1e-9} SOL to {to}",
                 '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)
     except Exception as e:
         return json.dumps({
             'status': HTTPStatus.BAD_REQUEST,
             'msg': msg,
         })
示例#12
0
    def create_account(
        self,
        owner: PublicKey,
        skip_confirmation: bool = False,
    ) -> PublicKey:
        """Create and initialize a new account.

        This account may then be used as a `transfer()` or `approve()` destination.

        :param owner: User account that will own the new account.
        :param skip_confirmation: (optional) Option to skip transaction confirmation.
        :return: Public key of the new empty account.

        If skip confirmation is set to `False`, this method will block for at most 30 seconds
        or until the transaction is confirmed.
        """
        new_account = Account()
        # Allocate memory for the account
        balance_needed = Token.get_min_balance_rent_for_exempt_for_account(
            self._conn)
        # Construct transaction
        txn = Transaction()
        txn.add(
            sp.create_account(
                sp.CreateAccountParams(
                    from_pubkey=self.payer.public_key(),
                    new_account_pubkey=new_account.public_key(),
                    lamports=balance_needed,
                    space=ACCOUNT_LAYOUT.sizeof(),
                    program_id=self.program_id,
                )))
        txn.add(
            spl_token.initialize_account(
                spl_token.InitializeAccountParams(
                    account=new_account.public_key(),
                    mint=self.pubkey,
                    owner=owner,
                    program_id=self.program_id)))
        # Send the two instructions
        self._conn.send_transaction(txn,
                                    self.payer,
                                    new_account,
                                    opts=TxOpts(
                                        skip_preflight=True,
                                        skip_confirmation=skip_confirmation))
        return new_account.public_key()
示例#13
0
 def create_sol_account(self):
     account = SolanaAccount()
     print(
         f"New solana account created: {account.public_key().to_base58()}. Airdropping..."
     )
     self.solana_client.request_airdrop(account.public_key(),
                                        1000_000_000_000, Confirmed)
     return account
示例#14
0
    def add_signer(self, signer: Account) -> None:
        """Fill in a signature for a partially signed Transaction.

        The `signer` must be the corresponding `Account` for a `PublicKey` that was
        previously provided to `signPartial`
        """
        signed_msg = signer.sign(self.serialize_message())
        self.add_signature(signer.public_key(), signed_msg.signature)
示例#15
0
def test_settle_fund(
    bootstrapped_market: Market,
    stubbed_payer: Account,
    stubbed_quote_wallet: Account,
    stubbed_base_wallet: Account,
):
    open_order_accounts = bootstrapped_market.find_open_orders_accounts_for_owner(
        stubbed_payer.public_key())

    for open_order_account in open_order_accounts:
        assert "error" not in bootstrapped_market.settle_funds(
            stubbed_payer,
            open_order_account,
            stubbed_base_wallet.public_key(),
            stubbed_quote_wallet.public_key(),
            opts=TxOpts(skip_confirmation=False),
        )
示例#16
0
def test_transfer_signatures(stubbed_blockhash):
    """Test signing transfer transactions."""
    acc1, acc2 = Account(), Account()
    transfer1 = sp.transfer(
        sp.TransferParams(from_pubkey=acc1.public_key(),
                          to_pubkey=acc2.public_key(),
                          lamports=123))
    transfer2 = sp.transfer(
        sp.TransferParams(from_pubkey=acc2.public_key(),
                          to_pubkey=acc1.public_key(),
                          lamports=123))
    txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(
        transfer1, transfer2)
    txn.sign(acc1, acc2)

    expected = txlib.Transaction(recent_blockhash=stubbed_blockhash,
                                 signatures=txn.signatures).add(
                                     transfer1, transfer2)
    assert txn == expected
示例#17
0
 def make_cancel_order_by_client_id_instruction(
         self, owner: Account, open_orders_account: PublicKey,
         client_id: int) -> TransactionInstruction:
     return instructions.cancel_order_by_client_id(
         instructions.CancelOrderByClientIDParams(
             market=self.state.public_key(),
             owner=owner.public_key(),
             open_orders=open_orders_account,
             request_queue=self.state.request_queue(),
             client_id=client_id,
             program_id=self.state.program_id(),
         ))
示例#18
0
def test_sign_partial(stubbed_blockhash):
    """Test paritally sigining a transaction."""
    acc1, acc2 = Account(), Account()
    transfer = sp.transfer(sp.TransferParams(from_pubkey=acc1.public_key(), to_pubkey=acc2.public_key(), lamports=123))
    partial_txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer)
    partial_txn.sign_partial(acc1, acc2.public_key())
    assert len(partial_txn.signature()) == txlib.SIG_LENGTH
    assert len(partial_txn.signatures) == 2
    assert not partial_txn.signatures[1].signature

    partial_txn.add_signer(acc2)
    expected_txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer)
    expected_txn.sign(acc1, acc2)
    assert partial_txn == expected_txn
示例#19
0
 def _create_mint_args(
     conn: Union[Client, AsyncClient],
     payer: Account,
     mint_authority: PublicKey,
     decimals: int,
     program_id: PublicKey,
     freeze_authority: Optional[PublicKey],
     skip_confirmation: bool,
     balance_needed: int,
     cls: Union[Type[Token], Type[AsyncToken]],
 ) -> Tuple[Union[Token, AsyncToken], Transaction, Account, Account,
            TxOpts]:
     mint_account = Account()
     token = cls(conn, mint_account.public_key(), program_id,
                 payer)  # type: ignore
     # Construct transaction
     txn = Transaction()
     txn.add(
         sp.create_account(
             sp.CreateAccountParams(
                 from_pubkey=payer.public_key(),
                 new_account_pubkey=mint_account.public_key(),
                 lamports=balance_needed,
                 space=MINT_LAYOUT.sizeof(),
                 program_id=program_id,
             )))
     txn.add(
         spl_token.initialize_mint(
             spl_token.InitializeMintParams(
                 program_id=program_id,
                 mint=mint_account.public_key(),
                 decimals=decimals,
                 mint_authority=mint_authority,
                 freeze_authority=freeze_authority,
             )))
     return token, txn, payer, mint_account, TxOpts(
         skip_confirmation=skip_confirmation, skip_preflight=True)
示例#20
0
 def settle(self,
            api_endpoint,
            pool_account,
            winning_mint,
            skip_confirmation=True):
     msg = ""
     client = Client(api_endpoint)
     msg += "Initialized client"
     # Create account objects
     source_account = Account(self.private_key)
     # Signers
     signers = [source_account]
     # List non-derived accounts
     pool_account = PublicKey(pool_account)
     winning_mint_account = PublicKey(winning_mint)
     tx = Transaction()
     settle_ix = settle_instruction(
         pool_account,
         winning_mint_account,
         source_account.public_key(),
     )
     tx = tx.add(settle_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" | Settle successful, winner: {str(winning_mint_account)}",
             '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)
示例#21
0
def test_generate_account_from_secret_key():
    """Generate an account with provided secret key."""
    secret_key = bytes(
        [
            153,
            218,
            149,
            89,
            225,
            94,
            145,
            62,
            233,
            171,
            46,
            83,
            227,
            223,
            173,
            87,
            93,
            163,
            59,
            73,
            190,
            17,
            37,
            187,
            146,
            46,
            51,
            73,
            79,
            73,
            136,
            40,
        ]
    )
    acc = Account(secret_key)
    assert str(acc.public_key()) == "2q7pyhPwAwZ3QMfZrnAbDhnh9mDUqycszcpf86VgQxhF"
示例#22
0
 def settle_funds(  # pylint: disable=too-many-arguments
     self,
     owner: Account,
     open_orders: OpenOrdersAccount,
     base_wallet: PublicKey,
     quote_wallet: PublicKey,  # TODO: add referrer_quote_wallet.
     opts: TxOpts = TxOpts(),
 ) -> RPCResponse:
     # TODO: Handle wrapped sol accounts
     if open_orders.owner != owner.public_key():
         raise Exception("Invalid open orders account")
     vault_signer = PublicKey.create_program_address(
         [
             bytes(self.state.public_key()),
             self.state.vault_signer_nonce().to_bytes(8, byteorder="little")
         ],
         self.state.program_id(),
     )
     transaction = Transaction()
     transaction.add(
         self.make_settle_funds_instruction(open_orders, base_wallet,
                                            quote_wallet, vault_signer))
     return self._conn.send_transaction(transaction, owner, opts=opts)
示例#23
0
    def _create_wrapped_native_account_args(
        program_id: PublicKey,
        owner: PublicKey,
        payer: Account,
        amount: int,
        skip_confirmation: bool,
        balance_needed: int,
    ) -> Tuple[PublicKey, Transaction, Account, Account, TxOpts]:
        new_account = Account()
        # Allocate memory for the account
        # Construct transaction
        txn = Transaction()
        txn.add(
            sp.create_account(
                sp.CreateAccountParams(
                    from_pubkey=payer.public_key(),
                    new_account_pubkey=new_account.public_key(),
                    lamports=balance_needed,
                    space=ACCOUNT_LAYOUT.sizeof(),
                    program_id=program_id,
                )))

        txn.add(
            sp.transfer(
                sp.TransferParams(from_pubkey=payer.public_key(),
                                  to_pubkey=new_account.public_key(),
                                  lamports=amount)))

        txn.add(
            spl_token.initialize_account(
                spl_token.InitializeAccountParams(
                    account=new_account.public_key(),
                    mint=WRAPPED_SOL_MINT,
                    owner=owner,
                    program_id=program_id)))

        return new_account.public_key(), txn, payer, new_account, TxOpts(
            skip_confirmation=skip_confirmation)
示例#24
0
quote_ccy = pair.split("/")[0]
quote_ccy_mint = {}
for mkt in get_token_mints():
    quote_ccy_mint.update({mkt.name: mkt.address})
print("Token Mint is: {}".format(quote_ccy_mint[quote_ccy]))

# %%

# Get private key and use that the create a new account
#pubkey = "GKksmU6hSJ2X7zz1mcE3Qhr7DDEpvxqbygzb17SxygUD"
f = open('./my-solana-wallet/my-keypair.json')
private_key = json.load(f)
mid = len(private_key) // 2
private_key = private_key[:mid]  # to 32 bytes
payer = Account(private_key)  # Your account to pay fees
print("Public Key is: {}".format(payer.public_key()))

# %%

cc = conn("https://api.mainnet-beta.solana.com/")

quote_token = Token(
    cc,
    pubkey=PublicKey(quote_ccy_mint[quote_ccy]),  # mint address of token
    program_id=TOKEN_PROGRAM_ID,
    payer=payer,
)

quote_wallet = quote_token.create_account(
    payer.public_key(),
    skip_confirmation=False)  # Make sure you send tokens to this address
示例#25
0
def test_order_placement_cancellation_cycle(
    bootstrapped_market: Market,
    stubbed_payer: Account,
    stubbed_quote_wallet: Account,
    stubbed_base_wallet: Account,
):
    initial_request_len = len(bootstrapped_market.load_request_queue())
    bootstrapped_market.place_order(
        payer=stubbed_quote_wallet.public_key(),
        owner=stubbed_payer,
        side=Side.Buy,
        order_type=OrderType.Limit,
        limit_price=1000,
        max_quantity=3000,
        opts=TxOpts(skip_confirmation=False),
    )

    request_queue = bootstrapped_market.load_request_queue()
    # 0 request after matching.
    assert len(request_queue) == initial_request_len + 1

    # There should be no bid order.
    bids = bootstrapped_market.load_bids()
    assert sum(1 for _ in bids) == 0

    # There should be no ask order.
    asks = bootstrapped_market.load_asks()
    assert sum(1 for _ in asks) == 0

    bootstrapped_market.place_order(
        payer=stubbed_base_wallet.public_key(),
        owner=stubbed_payer,
        side=Side.Sell,
        order_type=OrderType.Limit,
        limit_price=1500,
        max_quantity=3000,
        opts=TxOpts(skip_confirmation=False),
    )

    # The two order shouldn't get executed since there is a price difference of 1
    bootstrapped_market.match_orders(
        stubbed_payer,
        2,
        opts=TxOpts(skip_confirmation=False),
    )

    # There should be 1 bid order that we sent earlier.
    bids = bootstrapped_market.load_bids()
    assert sum(1 for _ in bids) == 1

    # There should be 1 ask order that we sent earlier.
    asks = bootstrapped_market.load_asks()
    assert sum(1 for _ in asks) == 1

    for bid in bids:
        bootstrapped_market.cancel_order(stubbed_payer,
                                         bid,
                                         opts=TxOpts(skip_confirmation=False))

    bootstrapped_market.match_orders(stubbed_payer,
                                     1,
                                     opts=TxOpts(skip_confirmation=False))

    # All bid order should have been cancelled.
    bids = bootstrapped_market.load_bids()
    assert sum(1 for _ in bids) == 0

    for ask in asks:
        bootstrapped_market.cancel_order(stubbed_payer,
                                         ask,
                                         opts=TxOpts(skip_confirmation=False))

    bootstrapped_market.match_orders(stubbed_payer,
                                     1,
                                     opts=TxOpts(skip_confirmation=False))

    # All ask order should have been cancelled.
    asks = bootstrapped_market.load_asks()
    assert sum(1 for _ in asks) == 0
示例#26
0
class Test_read_only_accounts(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.create_token_mint(cls)
        cls.deploy_erc20_wrapper_contract(cls)
        cls.deploy_test_contract(cls)

    def account_exists(self, key: PublicKey) -> Boolean:
        info = self.solana_client.get_account_info(key)
        info["result"]["value"] is not None

    def create_token_mint(self):
        self.solana_client = SolanaClient(solana_url)

        with open("proxy/operator-keypairs/id.json") as f:
            d = json.load(f)
        self.solana_account = SolanaAccount(d[0:32])
        self.solana_client.request_airdrop(self.solana_account.public_key(),
                                           1000_000_000_000, Confirmed)

        while True:
            balance = self.solana_client.get_balance(
                self.solana_account.public_key(), Confirmed)["result"]["value"]
            if balance > 0:
                break
            sleep(1)
        print('create_token_mint mint, SolanaAccount: ',
              self.solana_account.public_key())

        self.token = SplToken.create_mint(
            self.solana_client,
            self.solana_account,
            self.solana_account.public_key(),
            9,
            TOKEN_PROGRAM_ID,
        )

    def deploy_erc20_wrapper_contract(self):
        self.wrapper = ERC20Wrapper(proxy, "NEON", "NEON", self.token, admin,
                                    self.solana_account,
                                    PublicKey(EVM_LOADER_ID))
        self.wrapper.deploy_wrapper()

    def deploy_test_contract(self):
        compiled = compile_source(CONTRACT)
        id, interface = compiled.popitem()
        contract = proxy.eth.contract(abi=interface['abi'],
                                      bytecode=interface['bin'])
        trx = proxy.eth.account.sign_transaction(
            dict(nonce=proxy.eth.get_transaction_count(admin.address),
                 chainId=proxy.eth.chain_id,
                 gas=987654321,
                 gasPrice=1000000000,
                 to='',
                 value=0,
                 data=contract.bytecode), admin.key)
        signature = proxy.eth.send_raw_transaction(trx.rawTransaction)
        receipt = proxy.eth.wait_for_transaction_receipt(signature)

        self.contract = proxy.eth.contract(address=receipt.contractAddress,
                                           abi=contract.abi)

    def test_balanceOf(self):
        account = proxy.eth.account.create()

        solana_account = self.wrapper.get_neon_account_address(account.address)
        self.assertFalse(self.account_exists(solana_account))

        nonce = proxy.eth.get_transaction_count(admin.address)
        tx = self.contract.functions.balanceOf(
            account.address).buildTransaction({"nonce": nonce})
        tx = proxy.eth.account.sign_transaction(tx, admin.key)

        tx_hash = proxy.eth.send_raw_transaction(tx.rawTransaction)

        tx_receipt = proxy.eth.wait_for_transaction_receipt(tx_hash)
        self.assertIsNotNone(tx_receipt)
        self.assertEqual(tx_receipt.status, 1)

        self.assertFalse(self.account_exists(solana_account))

    def test_erc20_balanceOf(self):
        erc20 = self.wrapper.erc20_interface()

        account = proxy.eth.account.create()

        solana_account = self.wrapper.get_neon_account_address(account.address)
        self.assertFalse(self.account_exists(solana_account))

        token_account = self.wrapper.get_neon_erc20_account_address(
            account.address)
        self.assertFalse(self.account_exists(token_account))

        nonce = proxy.eth.get_transaction_count(admin.address)
        tx = erc20.functions.balanceOf(account.address).buildTransaction(
            {"nonce": nonce})
        tx = proxy.eth.account.sign_transaction(tx, admin.key)

        tx_hash = proxy.eth.send_raw_transaction(tx.rawTransaction)

        tx_receipt = proxy.eth.wait_for_transaction_receipt(tx_hash)
        self.assertIsNotNone(tx_receipt)
        self.assertEqual(tx_receipt.status, 1)

        self.assertFalse(self.account_exists(solana_account))
        self.assertFalse(self.account_exists(token_account))
示例#27
0
class GridStrategy(object):
    def __init__(self, upper: float, lower: float, amount: float, grid: int,
                 pair: str, base: str, quote: str, owner: str, private: str):
        """
        :params upper: price up
        :params lower: price down
        :params amount: amount of the order
        :params grid: amount of grid
        :params pair: dexlab trading pair address
        :params base: youur base coin address for trading
        :params quote: your quote coin address for trading
        :params owner: your solana wallet address
        :params private: your private key for pay the transaction gas
        """

        self.upper = upper
        self.lower = lower
        self.amount = amount
        self.grid = grid
        self.pair = pair
        self.base = base
        self.quote = quote
        self.owner = owner
        self.key = base58.b58decode(private)
        self.payer = Account(self.key[:32])
        self.client = Client('', '')
        self.cc = conn('https://api.mainnet-beta.solana.com/')
        self.market = Market.load(
            self.cc,
            PublicKey(self.pair),
            program_id=PublicKey(
                '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'))
        try:
            self.open_acc = self.market.find_open_orders_accounts_for_owner(
                self.payer.public_key())[0].address
        except:
            self.open_acc = ''
        self.base_decimal = self.market.state.base_spl_token_decimals()
        self.quote_decimal = self.market.state.quote_spl_token_decimals()
        print(f'Initialize...\n\n'
              f'----parameters----\n\n'
              f'upper: {self.upper}\n'
              f'lower: {self.lower}\n'
              f'amount: {self.amount}\n'
              f'grid: {self.grid}\n'
              f'base decimal: {self.base_decimal}\n'
              f'quote decimal: {self.quote_decimal}\n'
              f'pair: {self.pair}\n'
              f'base: {self.base}\n'
              f'quote: {self.quote}\n'
              f'owner: {self.owner}\n'
              f'open orders account: {self.open_acc}\n'
              f'key: {self.key[:32]}\n\n'
              f'----start----\n')

    def _get_orders(self):
        """
        :return: a dict contains price and client id Ex: {price: client}
        """

        orders = self.market.load_orders_for_owner(PublicKey(self.owner))
        order_table = {}
        for o in orders:
            order_table[o.client_id] = o.info.price
        return order_table

    def _get_last_price(self):
        """
        :return: last price (float)
        """

        return float(
            self.client.get_public_single_market_price(self.pair)['price'])

    def _buy_func(self, price, client_id):
        self.market.place_order(payer=PublicKey(self.base),
                                owner=self.payer,
                                side=Side.BUY,
                                order_type=OrderType.LIMIT,
                                limit_price=price,
                                max_quantity=abs(self.amount),
                                client_id=client_id,
                                opts=TxOpts(skip_preflight=True))
        print(
            f'Client ID: {client_id}; Price {price}; Amount: {self.amount}; Open: BUY'
        )

    def _sell_func(self, price, client_id):
        self.market.place_order(payer=PublicKey(self.quote),
                                owner=self.payer,
                                side=Side.SELL,
                                order_type=OrderType.LIMIT,
                                limit_price=price,
                                max_quantity=abs(self.amount),
                                client_id=client_id,
                                opts=TxOpts(skip_preflight=True))
        print(
            f'Client ID: {client_id}; Price {price}; Amount: {self.amount}; Open: SELL'
        )

    def cancel_order(self, client_id):
        """
        :return: a dict contains tx_hash and id
        """
        self.open_acc = self.market.find_open_orders_accounts_for_owner(
            self.payer.public_key())[0].address
        return self.market.cancel_order_by_client_id(
            self.payer, PublicKey(self.open_acc), client_id,
            TxOpts(skip_preflight=True))

    def cancel_pending(self):
        order_table = self._get_orders()
        for o in order_table.keys():
            self.cancel_order(o)

    def on_exit(self):
        if True:
            print(f'----Exit----\n\n' f'Closing all open orders...\n')
            self.cancel_pending()
        print('----Success----')

    def update_order(self, order_table, distance, last_prcie):
        for i in range(self.grid):
            if (i + 1) not in order_table:
                if (self.lower + i * distance) < last_prcie:
                    #self._buy_func(round((self.lower + i * distance), self.base_decimal), i + 1)
                    print(
                        f'Client ID: {i + 1}; Price {round((self.lower + i * distance), self.base_decimal)}; Amount: {self.amount}; Open: BUY'
                    )
                elif (self.lower + i * distance) > last_prcie:
                    #self._sell_func(round((self.lower + i * distance), self.quote_decimal), i + 1)
                    print(
                        f'Client ID: {i + 1}; Price {round((self.lower + i * distance), self.quote_decimal)}; Amount: {self.amount}; Open: SELL'
                    )

    def griding(self):
        """
        Main Logic
        """

        distance = (self.upper - self.lower) / self.grid
        order_table = self._get_orders()
        last_prcie = self._get_last_price()
        print(f'Current Price: {last_prcie}\n')
        print('----place orders----')
        self.update_order(order_table, distance, last_prcie)
示例#28
0
 def initialize(self,
                api_endpoint,
                escrow_mint,
                decimals=2,
                skip_confirmation=True):
     msg = ""
     # Initialize Clinet
     client = Client(api_endpoint)
     msg += "Initialized client"
     # Create account objects
     source_account = Account(self.private_key)
     pool = Account()
     long_escrow = Account()
     short_escrow = Account()
     long_mint = Account()
     short_mint = Account()
     # List non-derived accounts
     pool_account = pool.public_key()
     escrow_mint_account = PublicKey(escrow_mint)
     escrow_account = long_escrow.public_key()
     long_token_mint_account = long_mint.public_key()
     short_token_mint_account = short_mint.public_key()
     mint_authority_account = source_account.public_key()
     update_authority_account = source_account.public_key()
     token_account = PublicKey(TOKEN_PROGRAM_ID)
     system_account = PublicKey(SYSTEM_PROGRAM_ID)
     rent_account = PublicKey(SYSVAR_RENT_ID)
     msg += " | Gathered accounts"
     # List signers
     signers = [
         source_account, long_mint, short_mint, long_escrow, short_escrow,
         pool
     ]
     # Start transaction
     tx = Transaction()
     # Create Token Metadata
     init_binary_option_ix = initialize_binary_option_instruction(
         pool_account,
         escrow_mint_account,
         escrow_account,
         long_token_mint_account,
         short_token_mint_account,
         mint_authority_account,
         update_authority_account,
         token_account,
         system_account,
         rent_account,
         decimals,
     )
     tx = tx.add(init_binary_option_ix)
     msg += f" | Creating binary option"
     # Send request
     try:
         response = client.send_transaction(
             tx,
             *signers,
             opts=types.TxOpts(skip_confirmation=skip_confirmation))
         return json.dumps({
             'status':
             HTTPStatus.OK,
             'binary_option':
             str(pool_account),
             'msg':
             msg +
             f" | Successfully created binary option {str(pool_account)}",
             '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)
示例#29
0
class TestAirdropperIntegration(TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.create_token_mint(cls)
        cls.deploy_erc20_wrapper_contract(cls)
        cls.acc_num = 0

    def create_token_mint(self):
        self.solana_client = SolanaClient(SOLANA_URL)

        with open("proxy/operator-keypairs/id.json") as f:
            d = json.load(f)
        self.mint_authority = SolanaAccount(d[0:32])
        self.solana_client.request_airdrop(self.mint_authority.public_key(),
                                           1000_000_000_000, Confirmed)

        while True:
            balance = self.solana_client.get_balance(
                self.mint_authority.public_key(), Confirmed)["result"]["value"]
            if balance > 0:
                break
            sleep(1)
        print('create_token_mint mint, SolanaAccount: ',
              self.mint_authority.public_key())

        self.token = SplToken.create_mint(
            self.solana_client,
            self.mint_authority,
            self.mint_authority.public_key(),
            9,
            TOKEN_PROGRAM_ID,
        )

    def deploy_erc20_wrapper_contract(self):
        self.wrapper = ERC20Wrapper(proxy, NAME, SYMBOL, self.token, admin,
                                    self.mint_authority, EVM_LOADER_ID)
        self.wrapper.deploy_wrapper()

    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),
            ])

    def create_sol_account(self):
        account = SolanaAccount()
        print(
            f"New solana account created: {account.public_key().to_base58()}. Airdropping..."
        )
        self.solana_client.request_airdrop(account.public_key(),
                                           1000_000_000_000, Confirmed)
        return account

    def create_token_account(self, owner: PublicKey, mint_amount: int):
        new_token_account = self.wrapper.create_associated_token_account(
            owner, self.mint_authority)
        self.wrapper.mint_to(new_token_account, mint_amount)
        return new_token_account

    def create_eth_account(self):
        self.acc_num += 1
        account = proxy.eth.account.create(
            f'neonlabsorg/proxy-model.py/issues/344/eth_account{self.acc_num}')
        print(f"NEON account created: {account.address}")
        return account

    def test_success_airdrop_simple_case(self):
        from_owner = self.create_sol_account()
        mint_amount = 1000_000_000_000
        from_spl_token_acc = self.create_token_account(from_owner.public_key(),
                                                       mint_amount)
        to_neon_acc = self.create_eth_account().address

        self.assertEqual(self.wrapper.get_balance(from_spl_token_acc),
                         mint_amount)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc), 0)

        TRANSFER_AMOUNT = 123456
        trx = Transaction()
        trx.add(
            self.create_account_instruction(to_neon_acc,
                                            from_owner.public_key()))
        trx.add(
            self.wrapper.create_neon_erc20_account_instruction(
                from_owner.public_key(), to_neon_acc))
        trx.add(
            self.wrapper.create_input_liquidity_instruction(
                from_owner.public_key(), from_spl_token_acc, to_neon_acc,
                TRANSFER_AMOUNT))

        opts = TxOpts(skip_preflight=True, skip_confirmation=False)
        print(self.solana_client.send_transaction(trx, from_owner, opts=opts))

        self.assertEqual(self.wrapper.get_balance(from_spl_token_acc),
                         mint_amount - TRANSFER_AMOUNT)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc),
                         TRANSFER_AMOUNT)

        wait_time = 0
        eth_balance = 0
        while wait_time < MAX_AIRDROP_WAIT_TIME:
            eth_balance = proxy.eth.get_balance(to_neon_acc)
            balance_ready = eth_balance > 0 and eth_balance < 10 * pow(10, 18)
            if balance_ready:
                break
            sleep(1)
            wait_time += 1
        print(f"Wait time for simple transaction (1 airdrop): {wait_time}")

        eth_balance = proxy.eth.get_balance(to_neon_acc)
        print("NEON balance is: ", eth_balance)
        self.assertTrue(
            eth_balance > 0 and
            eth_balance < 10 * pow(10, 18))  # 10 NEON is a max airdrop amount

    def test_success_airdrop_complex_case(self):
        from_owner = self.create_sol_account()
        mint_amount = 1000_000_000_000
        from_spl_token_acc = self.create_token_account(from_owner.public_key(),
                                                       mint_amount)
        to_neon_acc1 = self.create_eth_account().address
        to_neon_acc2 = self.create_eth_account().address

        self.assertEqual(self.wrapper.get_balance(from_spl_token_acc),
                         mint_amount)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc1), 0)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc2), 0)

        TRANSFER_AMOUNT1 = 123456
        TRANSFER_AMOUNT2 = 654321
        trx = Transaction()
        trx.add(
            self.create_account_instruction(to_neon_acc1,
                                            from_owner.public_key()))
        trx.add(
            self.create_account_instruction(to_neon_acc2,
                                            from_owner.public_key()))
        trx.add(
            self.wrapper.create_neon_erc20_account_instruction(
                from_owner.public_key(), to_neon_acc1))
        trx.add(
            self.wrapper.create_neon_erc20_account_instruction(
                from_owner.public_key(), to_neon_acc2))
        trx.add(
            self.wrapper.create_input_liquidity_instruction(
                from_owner.public_key(), from_spl_token_acc, to_neon_acc1,
                TRANSFER_AMOUNT1))
        trx.add(
            self.wrapper.create_input_liquidity_instruction(
                from_owner.public_key(), from_spl_token_acc, to_neon_acc2,
                TRANSFER_AMOUNT2))

        opts = TxOpts(skip_preflight=True, skip_confirmation=False)
        print(self.solana_client.send_transaction(trx, from_owner, opts=opts))

        self.assertEqual(self.wrapper.get_balance(from_spl_token_acc),
                         mint_amount - TRANSFER_AMOUNT1 - TRANSFER_AMOUNT2)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc1),
                         TRANSFER_AMOUNT1)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc2),
                         TRANSFER_AMOUNT2)

        wait_time = 0
        eth_balance1 = 0
        eth_balance2 = 0
        while wait_time < MAX_AIRDROP_WAIT_TIME:
            eth_balance1 = proxy.eth.get_balance(to_neon_acc1)
            eth_balance2 = proxy.eth.get_balance(to_neon_acc2)
            balance1_ready = eth_balance1 > 0 and eth_balance1 < 10 * pow(
                10, 18)
            balance2_ready = eth_balance2 > 0 and eth_balance2 < 10 * pow(
                10, 18)
            if balance1_ready and balance2_ready:
                break
            sleep(1)
            wait_time += 1
        print(f"Wait time for complex transaction (2 airdrops): {wait_time}")

        eth_balance1 = proxy.eth.get_balance(to_neon_acc1)
        eth_balance2 = proxy.eth.get_balance(to_neon_acc2)
        print("NEON balance 1 is: ", eth_balance1)
        print("NEON balance 2 is: ", eth_balance2)
        self.assertTrue(
            eth_balance1 > 0 and
            eth_balance1 < 10 * pow(10, 18))  # 10 NEON is a max airdrop amount
        self.assertTrue(
            eth_balance2 > 0 and
            eth_balance2 < 10 * pow(10, 18))  # 10 NEON is a max airdrop amount

    def test_no_airdrop(self):
        from_owner = self.create_sol_account()
        mint_amount = 1000_000_000_000
        from_spl_token_acc = self.create_token_account(from_owner.public_key(),
                                                       mint_amount)
        to_neon_acc = self.create_eth_account().address
        sleep(15)
        self.assertEqual(self.wrapper.get_balance(from_spl_token_acc),
                         mint_amount)
        self.assertEqual(self.wrapper.get_balance(to_neon_acc), 0)

        trx = Transaction()
        trx.add(
            self.create_account_instruction(to_neon_acc,
                                            from_owner.public_key()))
        trx.add(
            self.wrapper.create_neon_erc20_account_instruction(
                from_owner.public_key(), to_neon_acc))
        # No input liquidity

        opts = TxOpts(skip_preflight=True, skip_confirmation=False)
        print(self.solana_client.send_transaction(trx, from_owner, opts=opts))

        sleep(15)
        eth_balance = proxy.eth.get_balance(to_neon_acc)
        print("NEON balance is: ", eth_balance)
        self.assertEqual(eth_balance, 0)
示例#30
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)