Sending transactions

We can stand out two kinds of sending transactions from the Terminal. Although from user's point of view, it looks like one wholeness, each functionality is backed by different, complex pieces of code. The two kinds are:

  • Sending SOL

  • Sending SPL tokens

To perform the transfer user is obligated to make some necessary choices:

  • Enter recipient's public key

  • Enter amount he/she would like to send

  • Select token from menu

Part of code responsible for sending Solana:

    def send_solana(self, private_key_base58, recipient_public_key, amount):
        client = Client(self.endpoints['send_solana'])
        try:
            private_key_bytes = base58.b58decode(private_key_base58)
            keypair = Keypair.from_secret_key(private_key_bytes)
            recipient_pubkey = PublicKey(recipient_public_key)
            transaction = Transaction().add(
                transfer(
                    TransferParams(
                        from_pubkey=keypair.public_key,
                        to_pubkey=recipient_pubkey,
                        lamports=int(amount * 1e9)
                    )
                )
            )
            response = client.send_transaction(transaction, keypair, opts=TxOpts(skip_confirmation=False))
            if response.get('result'):
            
            (...)

Part of code necessary to sending SPL tokens:

def send_token(self, private_key_base58, recipient_public_key, token_mint_address, amount, decimals):
        client = Client(self.endpoints['send_token'])
        try:
            private_key_bytes = base58.b58decode(private_key_base58)
            sender_keypair = Keypair.from_secret_key(private_key_bytes)
            sender_public_key = sender_keypair.public_key
            recipient_public_key = PublicKey(recipient_public_key)
            token_mint = PublicKey(token_mint_address)

            sender_token_account = get_associated_token_address(sender_public_key, token_mint)
            recipient_token_account = get_associated_token_address(recipient_public_key, token_mint)

            recipient_account_info = client.get_account_info(recipient_token_account)
            transaction = Transaction()

            if recipient_account_info['result']['value'] is None:
                create_assoc_instr = create_associated_token_account(
                    payer=sender_public_key,
                    owner=recipient_public_key,
                    mint=token_mint
                )
                transaction.add(create_assoc_instr)

            amount_int = int(amount * (10 ** decimals))

            transfer_params = TransferCheckedParams(
                program_id=TOKEN_PROGRAM_ID,
                source=sender_token_account,
                mint=token_mint,
                dest=recipient_token_account,
                owner=sender_public_key,
                amount=amount_int,
                decimals=decimals
            )

            transfer_instr = transfer_checked(transfer_params)
            transaction.add(transfer_instr)

            response = client.send_transaction(transaction, sender_keypair, opts=TxOpts(skip_confirmation=False))
            if response.get('result'):
            
            (...)

Universal function:

def send_transaction(self, public_key, private_key_base58):
        recipient = self.recipient_entry.get()
        try:
            amount = float(self.amount_entry.get())
            token_info = self.selected_send_token_info
            if token_info is None:
                self.show_message("Selected token not found.", "Error")
                return

            symbol = token_info['symbol']
            if symbol == 'SOL':
                if amount > token_info['amount']:
                    self.show_message("Insufficient SOL balance. Please enter a valid amount.", "Error")
                    return
                else:
                    self.show_processing_indicator()
                    threading.Thread(target=self.send_solana_thread, args=(private_key_base58, recipient, amount), daemon=True).start()
            else:
                if amount > token_info['amount']:
                    self.show_message("Insufficient token balance. Please enter a valid amount.", "Error")
                    return
                else:
                    self.show_processing_indicator()
                    threading.Thread(target=self.send_token_thread, args=(private_key_base58, recipient, token_info, amount), daemon=True).start()
        except ValueError:
            self.show_message("Invalid amount. Please enter a number.", "Error")

Last updated