# Transactions history

History of last transactions can be checked if someone wishes. The program displays:

* Date
* Token (expressed as a ticker)
* Amount
* From
* To
* Hash
* Type (in/out)

What is more, most of data is clickable and direct you to solscan.io. Except that, there is a filter which allow to hide dust transactions, which are usually a spam.

<figure><img src="https://3670432737-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwJuUkk9Y24vVhd9jDCn1%2Fuploads%2FVlHK5HcmleiLloqpFZb4%2FXXX.png?alt=media&#x26;token=225d4840-3aac-4d48-8111-2c0d25fe9bb9" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Make sure that capacity of your RPC point is enough, "History" sends a lot of requests.
{% endhint %}

Loading:

```python
def load_transaction_history(self, public_key):
    self.load_more_button.configure(state="disabled")
    threading.Thread(target=self.fetch_transaction_history, args=(public_key,), daemon=True).start()
```

Fetching:

```python
def fetch_transaction_history(self, public_key):
    client = Client(self.endpoints['fetch_transaction_history'])
    try:
        signatures_response = client.get_signatures_for_address(
            PublicKey(public_key),
            limit=self.history_limit,
            before=None if self.history_offset == 0 else self.transaction_history[-1]['signature']
        )
        if not signatures_response['result']:
            self.after(0, lambda: self.show_message("No transactions found.", "History"))
            return

        signatures = signatures_response['result']
        if not signatures:
            self.after(0, lambda: self.show_message("No more transactions to load.", "History"))
            self.after(0, lambda: self.load_more_button.configure(state="normal"))
            return

        for sig in signatures:
            signature = sig['signature']
            txn_response = client.get_confirmed_transaction(signature, encoding='jsonParsed')
            if not txn_response['result']:
                continue
            txn = txn_response['result']
            meta = txn.get('meta', {})
            err = meta.get('err')
            if err is not None:
                continue
            transaction = txn.get('transaction', {})
            message = transaction.get('message', {})
            instructions = message.get('instructions', [])
            block_time = txn.get('blockTime')
            if block_time:
                date = datetime.fromtimestamp(block_time).strftime('%Y-%m-%d %H:%M:%S')
            else:
                date = "N/A"

            for instr in instructions:
                parsed = instr.get('parsed', {})
                if not parsed:
                    continue
                info = parsed.get('info', {})
                if parsed.get('type') not in ['transfer', 'transferChecked']:
                    continue
                source = info.get('source')
                destination = info.get('destination')
                if 'tokenAmount' in info:
                    mint = info.get('mint')
                    symbol = self.dexscreener_cache.get(mint, ('SPL', 0))[0]
                    token = symbol
                    amount = float(info.get('tokenAmount', {}).get('uiAmount', 0))
                    full_token_address = mint
                else:
                    amount = float(info.get('lamports', 0)) / 1e9
                    token = 'SOL'
                    full_token_address = 'N/A'

                token_type = 'In' if destination == str(public_key) else 'Out'
                source_short = f"{source[:3]}...{source[-4:]}" if source else "N/A"
                destination_short = f"{destination[:3]}...{destination[-4:]}" if destination else "N/A"
                signature_short = f"{signature[:3]}...{signature[-4:]}"

                transaction_entry = {
                    'signature': signature,
                    'token': token,
                    'full_token_address': full_token_address,
                    'amount': amount,
                    'from': source_short,
                    'full_from': source if source else 'N/A',
                    'to': destination_short,
                    'full_to': destination if destination else 'N/A',
                    'hash': signature_short,
                    'full_hash': signature,
                    'type': token_type,
                    'date': date
                }

                self.transaction_history.append(transaction_entry)
        self.history_offset += self.history_limit
        self.after(0, lambda: self.display_transaction_history())
    except Exception as e:
        print(f"Error fetching transaction history: {e}")
        self.after(0, lambda: self.show_message("Failed to fetch transaction history.", "Error"))
    finally:
        self.after(0, lambda: self.load_more_button.configure(state="normal"))
```

Displaying:

```python
def display_transaction_history(self):
    for item in self.transaction_tree.get_children():
        self.transaction_tree.delete(item)

    if self.sort_column:
        self.sort_transactions(self.sort_column)
    else:
        for idx, txn in enumerate(self.transaction_history):
            if self.hide_dust_var.get() and txn['amount'] < 0.001:
                continue

            date = txn['date']
            token = txn['token']
            amount = format_number(txn['amount'], 3)
            from_addr = txn['from']
            to_addr = txn['to']
            hash_short = txn['hash']
            txn_type = txn['type']

            row_tag = 'evenrow' if idx % 2 == 0 else 'oddrow'

            tree_item = self.transaction_tree.insert('', 'end', values=(date, token, amount, from_addr, to_addr, hash_short, txn_type),
                                                     tags=(row_tag, 'in_transaction' if txn_type == 'In' else 'out_transaction'))
            self.treeview_item_map[tree_item] = txn
```
