---
title: Accounts and Transaction Context
description: Read transaction fields, account metadata, block context, and
  shadow-stack data from the C SDK.
source_url:
  html: https://thru.org/docs/sdks/c-reference/accounts-and-transaction-context/
  md: https://thru.org/docs/sdks/c-reference/accounts-and-transaction-context.md
---

# Accounts and Transaction Context

Use this page when you need to inspect the current transaction, understand account indexing, or safely read account and block metadata.

## Transaction root

Most in-program reads start from:

```c
tsdk_txn_t const * txn = tsdk_get_txn( );
```

From there, the inline helpers in `tn_sdk_txn.h` expose the fields you usually care about.

## Transaction helper reference

| Helper | What it returns |
| - | - |
| `tsdk_txn_get_instr_data(txn)` | Pointer to instruction bytes. |
| `tsdk_txn_get_instr_data_sz(txn)` | Instruction byte length. |
| `tsdk_txn_get_msg(txn)` | Message portion of the transaction. |
| `tsdk_txn_get_msg_sz(txn_sz)` | Message size excluding trailing signature. |
| `tsdk_txn_get_fee_payer_signature(txn, txn_sz)` | Pointer to the trailing fee-payer signature. |
| `tsdk_txn_get_fee(txn)` | Requested fee. |
| `tsdk_txn_get_nonce(txn)` | Transaction nonce. |
| `tsdk_txn_get_start_slot(txn)` | First valid slot. |
| `tsdk_txn_get_expiry_slot(txn)` | Last valid slot derived from `start_slot + expiry_after`. |
| `tsdk_txn_get_chain_id(txn)` | Chain identifier. |
| `tsdk_txn_get_requested_compute_units(txn)` | Requested compute units. |
| `tsdk_txn_get_requested_memory_units(txn)` | Requested memory units. |
| `tsdk_txn_has_fee_payer_state_proof(txn)` | Whether a fee-payer proof is present. |
| `tsdk_txn_get_acct_addrs(txn)` | Pointer to fee payer, program, and remaining account pubkeys. |
| `tsdk_txn_account_cnt(txn)` | Total account count exposed to the transaction. |
| `tsdk_txn_readwrite_account_cnt(txn)` | Read-write account count from the header. |
| `tsdk_txn_readonly_account_cnt(txn)` | Read-only account count from the header. |
| `tsdk_txn_is_account_idx_writable(txn, idx)` | Whether the account index is writable in the transaction. |

`tsdk_txn_get_msg_sz(txn_sz)` is the one helper in this group that only needs the total transaction size. It computes `message size = txn_sz - TN_TXN_SIGNATURE_SZ`, so it does not need the transaction pointer.

## Account indexing

The public helpers assume transaction account indexing like this:

| Index range | Meaning |
| - | - |
| `0` | Fee payer |
| `1` | Current program account |
| `2+` | User-supplied read-write and read-only accounts |

Use `tsdk_is_account_idx_valid(idx)` before indexing transaction-linked account data.

## Account metadata

`tsdk_get_account_meta(account_idx)` returns a `tsdk_account_meta_t const *` with:

| Field | Meaning |
| - | - |
| `version` | Whether the metadata is present and versioned. |
| `flags` | Bitfield of account properties (see flag constants below). |
| `data_sz` | Account data size. |
| `seq` | Sequence number. |
| `owner` | Owner program pubkey. |
| `balance` | Native token balance. |
| `nonce` | Account nonce. |

`tsdk_account_exists(account_idx)` is a convenient existence check built on top of metadata version.

## Account flag constants

The `flags` field on `tsdk_account_meta_t` is a bitfield. Test individual flags with bitwise AND:

| Constant | Value | Meaning |
| - | - | - |
| `TSDK_ACCOUNT_FLAG_PROGRAM` | `0x01` | Account contains executable program code. |
| `TSDK_ACCOUNT_FLAG_PRIVILEGED` | `0x02` | Account has privileged system-level access. |
| `TSDK_ACCOUNT_FLAG_UNCOMPRESSABLE` | `0x04` | Account cannot be compressed. |
| `TSDK_ACCOUNT_FLAG_EPHEMERAL` | `0x08` | Account exists only for the current transaction. |
| `TSDK_ACCOUNT_FLAG_DELETED` | `0x10` | Account has been deleted. |
| `TSDK_ACCOUNT_FLAG_NEW` | `0x20` | Account has never existed before this transaction. |
| `TSDK_ACCOUNT_FLAG_COMPRESSED` | `0x40` | Account state is compressed (removed from active ledger). |

```c
tsdk_account_meta_t const * meta = tsdk_get_account_meta( account_idx );
if( meta->flags & TSDK_ACCOUNT_FLAG_PROGRAM ) {
  /* account is a program */
}
```

Use `tsys_account_set_flags(account_idx, flags)` to modify flags on accounts owned by the current program.

## Account data pointers

`tsdk_get_account_data_ptr(account_idx)` returns a raw pointer into the VM account-data segment.

Typical pattern:

```c
ushort account_idx = 2U;

if( !tsdk_is_account_idx_valid( account_idx ) ) tsdk_revert( 1UL );
if( !tsdk_account_exists( account_idx ) ) tsdk_revert( 2UL );

void * data = tsdk_get_account_data_ptr( account_idx );
tsdk_account_meta_t const * meta = tsdk_get_account_meta( account_idx );
```

## Block context

| Helper | Use it for |
| - | - |
| `tsdk_get_current_block_ctx()` | Current slot, block time, block price, state root, current block hash, and block producer. |
| `tsdk_get_past_block_ctx(blocks_in_past)` | Access a previous block context spaced by `TSDK_BLOCK_CTX_VM_SPACING`. |

The block context struct is `tsdk_block_ctx_t`.

## Shadow stack and current program identity

| Helper | Use it for |
| - | - |
| `tsdk_get_shadow_stack()` | Read call depth and CPI frame information. |
| `tsdk_get_current_program_acc_idx()` | Resolve the current program’s transaction account index. |
| `tsdk_get_current_program_acc_addr()` | Resolve the current program’s pubkey. |
| `tsdk_is_program_reentrant()` | Detect whether the current program already appears lower in the call chain. |
| `tsdk_is_account_authorized_by_idx(...)` | Check effective authorization by account index, including CPI auth/deauth state. |
| `tsdk_is_account_authorized_by_pubkey(...)` | Check effective authorization by pubkey. |
| `tsdk_is_account_owned_by_current_program(...)` | Check whether the current program owns an account. |

## Notes

- Do not assume every account index is valid just because the instruction payload contains it.
- Metadata and data pointers come from VM-managed memory; treat them as borrowed pointers, not owned allocations.
- Writable status comes from transaction context and syscalls, not from the presence of a data pointer alone.
