# 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

<figure><img src="/files/RdczCy045BamfLdr3hxQ" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Using default, public Solana endpoint ("<https://api.mainnet-beta.solana.com>") isn't recommended. This endpoint doesn't allow the program to get the execute confirmation (among others disadvantages), so always make sure before you repeat a transfer. Read more in "Endpoints" section.
{% endhint %}

Part of code responsible for sending Solana:

```python
    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:

```python
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:

```python
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")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://low-caps-hub.gitbook.io/lowcapshubterminal/wallet-section/sending-transactions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
