---
title: "Reading from Intelligent Contracts"
description: "Read Intelligent Contract state at the latest final or latest non-final snapshot with GenLayerJS."
source: https://docs.genlayer.com/developers/decentralized-applications/reading-data
last_updated: 2026-09-03
---

# Reading from Intelligent Contracts

Public view methods read Intelligent Contract state without submitting a consensus transaction. They do not need a transaction fee or signing account.

## Basic read

```typescript
import { createClient } from 'genlayer-js';
import { localnet } from 'genlayer-js/chains';
import { TransactionHashVariant } from 'genlayer-js/types';

const client = createClient({ chain: localnet });

const result = await client.readContract({
  address: contractAddress,
  functionName: 'get_complete_storage',
  args: [],
  transactionHashVariant: TransactionHashVariant.LATEST_FINAL,
});
```

## Choose the state snapshot

| Variant | Use it for |
|:--|:--|
| `LATEST_FINAL` | Durable application state after finalization. This is the conservative default for accounting and irreversible UI decisions. |
| `LATEST_NONFINAL` | The newest available non-final state. Use it for responsive interfaces that can tolerate an appeal or recomputation changing the result. |

Omit `transactionHashVariant` when the chain's default is appropriate. Be explicit when an application depends on finality semantics.

## Arguments and return formats

```typescript
const userInfo = await client.readContract({
  address: contractAddress,
  functionName: 'get_user_info',
  args: [userId],
  transactionHashVariant: TransactionHashVariant.LATEST_FINAL,
});
```

Use `kwargs` instead of `args` when the contract API is clearer with named arguments. The default result is decoded into GenLayer calldata values. Advanced consumers can request `rawReturn: true` for raw bytes or `jsonSafeReturn: true` where supported by the selected client surface.

## Reads after a write

Waiting for a decision and reading the latest non-final state is faster, but that state can still move. Waiting for finalization and reading `LATEST_FINAL` gives a durable pair:

```typescript
await client.waitForFinalization({ hash: txId });

const value = await client.readContract({
  address: contractAddress,
  functionName: 'get_storage',
  args: [],
  transactionHashVariant: TransactionHashVariant.LATEST_FINAL,
});
```

## Error handling

```typescript
try {
  const value = await client.readContract({
    address: contractAddress,
    functionName: 'get_data',
    args: [],
  });
  console.log(value);
} catch (error) {
  console.error('Contract read failed', error);
}
```

Do not classify errors only by matching an English message. Preserve the RPC error data so the application can decode a custom error with the deployment's matching ABI and the [Error & Revert Reference](/developers/error-reference).

## Related

- [Writing to Intelligent Contracts](./writing-data)
- [Querying a Transaction](./querying-a-transaction)
- [GenLayerJS contract API](/api-references/genlayer-js/contracts)
