# SDK Reference: EVM Client
Source: https://docs.chain.link/cre/reference/sdk/evm-client-ts
Last Updated: 2026-02-16


This page provides a reference for the `EVMClient`, the low-level tool for all interactions with EVM-compatible blockchains. The client includes a comprehensive set of read, write, and utility methods for building chain-aware workflows.

## Client instantiation

To use the client, you must instantiate it with the numeric `ChainSelector` ID for the blockchain you intend to interact with.

```typescript
import { EVMClient, getNetwork } from "@chainlink/cre-sdk"

// Get network information by chain selector name
const network = getNetwork({
  chainFamily: "evm",
  chainSelectorName: "ethereum-testnet-sepolia",
})

if (!network) {
  throw new Error("Network not found")
}

// Instantiate a client for Ethereum Sepolia
const evmClient = new EVMClient(network.chainSelector.selector)
```

> **NOTE: What is a Chain Selector?**
>
> A Chain Selector is a unique identifier for a blockchain network. It is used to select the correct blockchain client
> for the workflow. See the [Chain Selectors](#chain-selectors) section below for a complete list of supported networks
> and usage examples.

### Using `getNetwork()` helper

The `getNetwork()` utility function allows you to look up network information by chain selector name or numeric ID. This is the recommended approach as it provides type-safe access to chain metadata and validates network configurations.

```typescript
import { getNetwork } from "@chainlink/cre-sdk"

const network = getNetwork({
  chainFamily: "evm",
  chainSelectorName: "ethereum-testnet-sepolia",
})

// Access network properties
// network.chainSelector.selector → 16015286601757825753n (bigint)
// network.chainSelector.name → "ethereum-testnet-sepolia"
// network.family → "evm"
```

## Read & query methods

These methods are used to read data from the blockchain without creating a transaction.

### `callContract()`

Executes a `view` or `pure` function on a smart contract. This method returns an object with a `.result()` method that blocks until the call completes.

**Signature:**

```typescript
callContract(
  runtime: Runtime<unknown>,
  input: CallContractRequest | CallContractRequestJson
): { result: () => CallContractReply }
```

#### `CallContractRequest` / `CallContractRequestJson`

This is the main input object for the `callContract()` method.

| Field         | Type          | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `call`        | `CallMsgJson` | Yes      | Contains the actual details of the function call you want to make.                                                                                                                                                                                                                                                                                                                                                                                    |
| `blockNumber` | `BigIntJson`  | No       | The block number to query. Accepts:<br />• `LATEST_BLOCK_NUMBER` (default): the most recent block<br />• `LAST_FINALIZED_BLOCK_NUMBER`: a finalized block<br />• **`BigIntJson` object**: an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-ts#custom-block-depths) for conversion details).<br /><br />See [Finality and Confidence Levels](/cre/concepts/finality-ts) for finality strategies. |

#### `CallMsg` / `CallMsgJson`

This struct contains the core details of your onchain call.

| Field  | Type     | Required | Description                                                                                                                                      |
| ------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `from` | `string` | Yes      | The 20-byte address of the sender (hex string). For `view`/`pure` functions, use `zeroAddress` from viem as the sender doesn't typically matter. |
| `to`   | `string` | Yes      | The 20-byte address of the target contract (hex string).                                                                                         |
| `data` | `string` | Yes      | The ABI-encoded function call data (hex string), including the function selector and arguments.                                                  |

#### `CallContractReply`

This is the object returned by `.result()` when the `callContract()` method successfully completes.

| Field  | Type         | Description                                         |
| ------ | ------------ | --------------------------------------------------- |
| `data` | `Uint8Array` | The ABI-encoded data returned by the contract call. |

#### Usage example

```typescript
import { EVMClient, getNetwork, encodeCallMsg, bytesToHex, LAST_FINALIZED_BLOCK_NUMBER } from "@chainlink/cre-sdk"
import { encodeFunctionData, decodeFunctionResult, zeroAddress } from "viem"
import { Storage } from "../contracts/abi"

// Get network and instantiate client
const network = getNetwork({
  chainFamily: "evm",
  chainSelectorName: "ethereum-testnet-sepolia",
})
const evmClient = new EVMClient(network.chainSelector.selector)

// Encode the contract call data
const callData = encodeFunctionData({
  abi: Storage,
  functionName: "get",
})

// Call the contract
const contractCall = evmClient
  .callContract(runtime, {
    call: encodeCallMsg({
      from: zeroAddress, // Required by encodeCallMsg. For view/pure functions, the sender doesn't matter.
      to: "0x1234567890123456789012345678901234567890",
      data: callData,
    }),
    blockNumber: LAST_FINALIZED_BLOCK_NUMBER,
  })
  .result()

// Decode the result
const value = decodeFunctionResult({
  abi: Storage,
  functionName: "get",
  data: bytesToHex(contractCall.data),
})
```

***

### `filterLogs()`

Queries historical event logs that match a specific set of filter criteria. This method returns an object with a `.result()` method that blocks until the query completes.

**Signature:**

```typescript
filterLogs(
  runtime: Runtime<unknown>,
  input: FilterLogsRequest | FilterLogsRequestJson
): { result: () => FilterLogsReply }
```

#### `FilterLogsRequest` / `FilterLogsRequestJson`

| Field         | Type              | Required | Description                                                                                  |
| ------------- | ----------------- | -------- | -------------------------------------------------------------------------------------------- |
| `filterQuery` | `FilterQueryJson` | Yes      | A struct defining the filters for the log query, such as block range, addresses, and topics. |

#### `FilterLogsReply`

| Field  | Type    | Description                                          |
| ------ | ------- | ---------------------------------------------------- |
| `logs` | `Log[]` | An array of log objects that match the filter query. |

#### `Log` type

| Field         | Type           | Description                                                  |
| ------------- | -------------- | ------------------------------------------------------------ |
| `address`     | `Uint8Array`   | The 20-byte address of the contract that emitted the log.    |
| `topics`      | `Uint8Array[]` | An array of indexed log fields (32-byte arrays).             |
| `data`        | `Uint8Array`   | Non-indexed log data.                                        |
| `blockNumber` | `bigint`       | The block number where the log was emitted (optional).       |
| `txHash`      | `Uint8Array`   | The 32-byte transaction hash.                                |
| `txIndex`     | `number`       | The index of the transaction within the block.               |
| `blockHash`   | `Uint8Array`   | The 32-byte block hash.                                      |
| `index`       | `number`       | The index of the log within the transaction.                 |
| `removed`     | `boolean`      | `true` if the log was removed due to a chain reorganization. |

***

### `balanceAt()`

Retrieves the native token balance for a specific account. This method returns an object with a `.result()` method that blocks until the balance is retrieved.

**Signature:**

```typescript
balanceAt(
  runtime: Runtime<unknown>,
  input: BalanceAtRequest | BalanceAtRequestJson
): { result: () => BalanceAtReply }
```

#### `BalanceAtRequest` / `BalanceAtRequestJson`

| Field         | Type         | Required | Description                                                                                                                                                                                                                                                                                                                       |
| ------------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`     | `string`     | Yes      | The 20-byte address of the account to query (hex string).                                                                                                                                                                                                                                                                         |
| `blockNumber` | `BigIntJson` | No       | The block number to query. Accepts `LATEST_BLOCK_NUMBER` (default), `LAST_FINALIZED_BLOCK_NUMBER`, or a `BigIntJson` object for an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-ts#custom-block-depths)). See [Finality and Confidence Levels](/cre/concepts/finality-ts). |

#### `BalanceAtReply`

| Field     | Type     | Description                        |
| --------- | -------- | ---------------------------------- |
| `balance` | `bigint` | The balance of the account in Wei. |

***

### `estimateGas()`

Estimates the gas required to execute a specific transaction. This method returns an object with a `.result()` method that blocks until the estimation completes.

**Signature:**

```typescript
estimateGas(
  runtime: Runtime<unknown>,
  input: EstimateGasRequest | EstimateGasRequestJson
): { result: () => EstimateGasReply }
```

#### `EstimateGasRequest` / `EstimateGasRequestJson`

| Field | Type          | Required | Description                                             |
| ----- | ------------- | -------- | ------------------------------------------------------- |
| `msg` | `CallMsgJson` | Yes      | The transaction message to simulate for gas estimation. |

#### `EstimateGasReply`

| Field | Type     | Description                               |
| ----- | -------- | ----------------------------------------- |
| `gas` | `bigint` | The estimated amount of gas in gas units. |

***

### `getTransactionByHash()`

Retrieves a transaction by its hash. This method returns an object with a `.result()` method that blocks until the transaction is retrieved.

**Signature:**

```typescript
getTransactionByHash(
  runtime: Runtime<unknown>,
  input: GetTransactionByHashRequest | GetTransactionByHashRequestJson
): { result: () => GetTransactionByHashReply }
```

#### `GetTransactionByHashRequest` / `GetTransactionByHashRequestJson`

| Field  | Type     | Required | Description                                                  |
| ------ | -------- | -------- | ------------------------------------------------------------ |
| `hash` | `string` | Yes      | The 32-byte hash of the transaction to look up (hex string). |

#### `GetTransactionByHashReply`

| Field         | Type          | Description                       |
| ------------- | ------------- | --------------------------------- |
| `transaction` | `Transaction` | The transaction object, if found. |

#### `Transaction` type

| Field      | Type         | Description                           |
| ---------- | ------------ | ------------------------------------- |
| `nonce`    | `bigint`     | The nonce of the transaction.         |
| `gas`      | `bigint`     | The gas limit.                        |
| `to`       | `Uint8Array` | The 20-byte address of the recipient. |
| `data`     | `Uint8Array` | The transaction data payload.         |
| `hash`     | `Uint8Array` | The 32-byte transaction hash.         |
| `value`    | `bigint`     | The value transferred in Wei.         |
| `gasPrice` | `bigint`     | The gas price in Wei.                 |

***

### `getTransactionReceipt()`

Fetches the receipt for a transaction given its hash. This method returns an object with a `.result()` method that blocks until the receipt is retrieved.

**Signature:**

```typescript
getTransactionReceipt(
  runtime: Runtime<unknown>,
  input: GetTransactionReceiptRequest | GetTransactionReceiptRequestJson
): { result: () => GetTransactionReceiptReply }
```

#### `GetTransactionReceiptRequest` / `GetTransactionReceiptRequestJson`

| Field  | Type     | Required | Description                                       |
| ------ | -------- | -------- | ------------------------------------------------- |
| `hash` | `string` | Yes      | The 32-byte hash of the transaction (hex string). |

#### `GetTransactionReceiptReply`

| Field     | Type      | Description                               |
| --------- | --------- | ----------------------------------------- |
| `receipt` | `Receipt` | The transaction receipt object, if found. |

#### `Receipt` type

| Field               | Type         | Description                                                     |
| ------------------- | ------------ | --------------------------------------------------------------- |
| `status`            | `bigint`     | Transaction status: `1` for success, `0` for failure.           |
| `gasUsed`           | `bigint`     | The amount of gas used by the transaction.                      |
| `txIndex`           | `bigint`     | The index of the transaction within the block.                  |
| `blockHash`         | `Uint8Array` | The 32-byte block hash.                                         |
| `logs`              | `Log[]`      | An array of log objects emitted by the transaction.             |
| `txHash`            | `Uint8Array` | The 32-byte transaction hash.                                   |
| `effectiveGasPrice` | `bigint`     | The actual gas price paid per gas unit (optional).              |
| `blockNumber`       | `bigint`     | The block number where the transaction was included (optional). |
| `contractAddress`   | `Uint8Array` | The address of the deployed contract (if applicable).           |

***

### `headerByNumber()`

Retrieves a block header by its number. This method returns an object with a `.result()` method that blocks until the header is retrieved.

**Signature:**

```typescript
headerByNumber(
  runtime: Runtime<unknown>,
  input: HeaderByNumberRequest | HeaderByNumberRequestJson
): { result: () => HeaderByNumberReply }
```

#### `HeaderByNumberRequest` / `HeaderByNumberRequestJson`

| Field         | Type         | Required | Description                                                                                                                                                                                                                                                                                                                                                           |
| ------------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `blockNumber` | `BigIntJson` | No       | The number of the block to retrieve. Accepts `undefined` for `latest` (default), `LATEST_BLOCK_NUMBER`, `LAST_FINALIZED_BLOCK_NUMBER`, or a `BigIntJson` object for an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-ts#custom-block-depths)). See [Finality and Confidence Levels](/cre/concepts/finality-ts). |

#### `HeaderByNumberReply`

| Field    | Type     | Description                        |
| -------- | -------- | ---------------------------------- |
| `header` | `Header` | The block header object, if found. |

#### `Header` type

| Field         | Type         | Description                           |
| ------------- | ------------ | ------------------------------------- |
| `timestamp`   | `bigint`     | The Unix timestamp of the block.      |
| `blockNumber` | `bigint`     | The block number (optional).          |
| `hash`        | `Uint8Array` | The 32-byte block hash.               |
| `parentHash`  | `Uint8Array` | The 32-byte hash of the parent block. |

***

## Write methods

### `writeReport()`

Executes a state-changing transaction by submitting a cryptographically signed report to a designated receiver contract. This is the primary method for writing data onchain in CRE workflows.

**Signature:**

```typescript
writeReport(
  runtime: Runtime<unknown>,
  input: WriteCreReportRequest | WriteCreReportRequestJson
): { result: () => WriteReportReply }
```

#### `WriteCreReportRequest` / `WriteCreReportRequestJson`

| Field       | Type            | Required | Description                                                        |
| ----------- | --------------- | -------- | ------------------------------------------------------------------ |
| `receiver`  | `string`        | Yes      | The 20-byte address of the receiver contract to call (hex string). |
| `report`    | `Report`        | Yes      | The report object generated by `runtime.report()`.                 |
| `gasConfig` | `GasConfigJson` | No       | Gas limit configuration for the transaction.                       |

#### `GasConfig` / `GasConfigJson`

| Field      | Type     | Required | Description                        |
| ---------- | -------- | -------- | ---------------------------------- |
| `gasLimit` | `string` | Yes      | The gas limit for the transaction. |

#### `WriteReportReply`

| Field                             | Type                              | Description                                                                                                                                                |
| --------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `txStatus`                        | `TxStatus`                        | The final status of the transaction: `TX_STATUS_SUCCESS`, `TX_STATUS_REVERTED`, or `TX_STATUS_FATAL`.                                                      |
| `receiverContractExecutionStatus` | `ReceiverContractExecutionStatus` | The status of the receiver contract's execution: `RECEIVER_CONTRACT_EXECUTION_STATUS_SUCCESS` or `RECEIVER_CONTRACT_EXECUTION_STATUS_REVERTED` (optional). |
| `txHash`                          | `Uint8Array`                      | The 32-byte transaction hash of the onchain submission (optional).                                                                                         |
| `transactionFee`                  | `bigint`                          | The total fee paid for the transaction in Wei (optional).                                                                                                  |
| `errorMessage`                    | `string`                          | An error message if the transaction failed (optional).                                                                                                     |

#### `TxStatus` enum

- `TX_STATUS_SUCCESS`: The transaction was successful.
- `TX_STATUS_REVERTED`: The transaction reverted.
- `TX_STATUS_FATAL`: A fatal error occurred.

#### Usage example

```typescript
import { EVMClient, getNetwork, hexToBase64, bytesToHex } from "@chainlink/cre-sdk"
import { encodeFunctionData } from "viem"
import { ReserveManager } from "../contracts/abi"

// Encode the contract call data
const callData = encodeFunctionData({
  abi: ReserveManager,
  functionName: "updateReserves",
  args: [
    {
      totalMinted: 100n,
      totalReserve: 50n,
    },
  ],
})

// Generate a signed report
const reportResponse = runtime
  .report({
    encodedPayload: hexToBase64(callData),
    encoderName: "evm",
    signingAlgo: "ecdsa",
    hashingAlgo: "keccak256",
  })
  .result()

// Submit the report onchain
const writeResult = evmClient
  .writeReport(runtime, {
    receiver: "0x1234567890123456789012345678901234567890",
    report: reportResponse,
    gasConfig: {
      gasLimit: "1000000",
    },
  })
  .result()

runtime.log(`Transaction hash: ${bytesToHex(writeResult.txHash || new Uint8Array(32))}`)
```

***

## Log tracking methods

These methods manage stateful log tracking subscriptions.

### `registerLogTracking()`

Creates a persistent filter to track specific logs over time. This is a "fire-and-forget" operation that returns an empty result.

**Signature:**

```typescript
registerLogTracking(
  runtime: Runtime<unknown>,
  input: RegisterLogTrackingRequest | RegisterLogTrackingRequestJson
): { result: () => Empty }
```

#### `RegisterLogTrackingRequest` / `RegisterLogTrackingRequestJson`

| Field    | Type           | Required | Description                                                                                |
| -------- | -------------- | -------- | ------------------------------------------------------------------------------------------ |
| `filter` | `LPFilterJson` | Yes      | A struct defining the persistent log filter, including rate limits and retention policies. |

***

### `unregisterLogTracking()`

Removes a previously registered log tracking filter. This is a "fire-and-forget" operation that returns an empty result.

**Signature:**

```typescript
unregisterLogTracking(
  runtime: Runtime<unknown>,
  input: UnregisterLogTrackingRequest | UnregisterLogTrackingRequestJson
): { result: () => Empty }
```

#### `UnregisterLogTrackingRequest` / `UnregisterLogTrackingRequestJson`

| Field        | Type     | Description                              |
| ------------ | -------- | ---------------------------------------- |
| `filterName` | `string` | The unique name of the filter to remove. |

***

## Helper functions

The TypeScript SDK provides several helper functions for working with the EVM Client.

### `encodeCallMsg()`

Encodes a call message payload into a `CallMsgJson`, expected by the EVM capability.

**Signature:**

```typescript
function encodeCallMsg(payload: EncodeCallMsgPayload): CallMsgJson
```

**Parameters:**

```typescript
interface EncodeCallMsgPayload {
  from: Address // viem Address type (0x-prefixed hex string)
  to: Address
  data: Hex // viem Hex type (0x-prefixed hex string)
}
```

**Usage:**

```typescript
import { encodeCallMsg } from "@chainlink/cre-sdk"
import { zeroAddress } from "viem"

const callMsg = encodeCallMsg({
  from: zeroAddress,
  to: "0x1234567890123456789012345678901234567890",
  data: "0xabcdef",
})
```

***

### `bytesToHex()`

Converts a `Uint8Array` to a `0x`-prefixed hex string.

**Signature:**

```typescript
function bytesToHex(bytes: Uint8Array): Hex
```

***

### `hexToBase64()`

Converts a `0x`-prefixed hex string to a base64-encoded string. This is useful for preparing data for protobuf structures.

**Signature:**

```typescript
function hexToBase64(hex: Hex): string
```

***

### `protoBigIntToBigint()`

Converts a protobuf `BigInt` (returned by SDK methods like `headerByNumber`) to a native JavaScript `bigint`. Use this when you need to perform arithmetic on block numbers or other numeric values returned from the blockchain.

**Signature:**

```typescript
function protoBigIntToBigint(pb: ProtoBigInt): bigint
```

**Parameters:**

- `pb`: A protobuf `BigInt` object with `absVal` (Uint8Array) and `sign` (bigint) fields

**Returns:**

A native JavaScript `bigint` value.

**Usage:**

```typescript
import { protoBigIntToBigint } from "@chainlink/cre-sdk"

// Get the latest block number from the blockchain
const latestHeader = evmClient.headerByNumber(runtime, {}).result()

// Convert the protobuf BigInt to a native bigint for arithmetic
const latestBlockNum = protoBigIntToBigint(latestHeader.header.blockNumber)
const customBlock = latestBlockNum - 500n // Now you can do arithmetic

// latestBlockNum → e.g., 12345678n
// customBlock → e.g., 12345178n (500 blocks earlier)
```

See [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-ts#custom-block-depths) for a complete example.

***

### `blockNumber()`

Converts a native `bigint`, `number`, or `string` to the protobuf `BigInt` JSON format required by SDK methods. This is a convenience alias for `bigintToProtoBigInt`. Use this when specifying an explicit block height for contract calls or other blockchain queries.

**Signature:**

```typescript
function blockNumber(n: number | bigint | string): BigIntJson
```

**Parameters:**

- `n`: The block number as a native `bigint`, `number`, or `string`

**Returns:**

A `BigIntJson` object in the protobuf format expected by SDK methods.

**Usage:**

```typescript
import { blockNumber, encodeCallMsg } from "@chainlink/cre-sdk"
import { zeroAddress } from "viem"

// Read from a specific historical block
const historicalBlock = 9767655n
const contractCall = evmClient
  .callContract(runtime, {
    call: encodeCallMsg({
      from: zeroAddress,
      to: contractAddress,
      data: callData,
    }),
    blockNumber: blockNumber(historicalBlock),
  })
  .result()
```

See [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-ts#custom-block-depths) for a complete example.

***

### `hexToBytes()`

Converts a `0x`-prefixed hex string to a `Uint8Array`.

**Signature:**

```typescript
function hexToBytes(hex: string): Uint8Array
```

**Usage:**

```typescript
import { hexToBytes } from "@chainlink/cre-sdk"

const bytes = hexToBytes("0xabcdef")
// → Uint8Array [171, 205, 239]
```

***

### `bigintToBytes()`

Converts a native JavaScript `bigint` to a big-endian `Uint8Array`. This is useful when you need to encode a `bigint` as raw bytes for protobuf fields or ABI encoding.

**Signature:**

```typescript
function bigintToBytes(n: bigint): Uint8Array
```

**Usage:**

```typescript
import { bigintToBytes } from "@chainlink/cre-sdk"

const bytes = bigintToBytes(256n)
// → Uint8Array [1, 0]
```

***

### `bytesToBigint()`

Converts a big-endian `Uint8Array` to a native JavaScript `bigint`. This is the inverse of `bigintToBytes()`.

**Signature:**

```typescript
function bytesToBigint(bytes: Uint8Array): bigint
```

**Usage:**

```typescript
import { bytesToBigint } from "@chainlink/cre-sdk"

const value = bytesToBigint(new Uint8Array([1, 0]))
// → 256n
```

***

### `bigintToProtoBigInt()`

Converts a native `bigint`, `number`, or `string` to the protobuf `BigIntJson` format used by SDK methods. The [`blockNumber()`](#blocknumber) function is a convenience alias for this function.

**Signature:**

```typescript
function bigintToProtoBigInt(n: number | bigint | string): BigIntJson
```

**Returns:**

A `BigIntJson` object with `absVal` (base64-encoded big-endian bytes) and `sign` (`"1"`, `"0"`, or `"-1"`).

**Usage:**

```typescript
import { bigintToProtoBigInt } from "@chainlink/cre-sdk"

const protoBigInt = bigintToProtoBigInt(12345678n)
// → { absVal: "ALxhTg==", sign: "1" }

const negative = bigintToProtoBigInt(-42n)
// → { absVal: "Kg==", sign: "-1" }

const zero = bigintToProtoBigInt(0n)
// → { absVal: "", sign: "0" }
```

See [Type Conversions](/cre/reference/sdk/type-conversions-ts#protobigint) for more details on the `ProtoBigInt` format.

***

### `prepareReportRequest()`

Prepares a report request with default EVM encoding parameters for use with `runtime.report()`. This helper simplifies report generation by automatically setting the standard encoding configuration (`evm`, `ecdsa`, `keccak256`) required for EVM-based workflows.

**Signature:**

```typescript
function prepareReportRequest(
  hexEncodedPayload: Hex,
  reportEncoder?: Exclude<ReportRequestJson, "encodedPayload">
): ReportRequestJson
```

**Parameters:**

- `hexEncodedPayload`: The hex-encoded payload (typically from `encodeFunctionData()`) to be signed by the DON
- `reportEncoder`: Optional. Custom report encoder configuration. Defaults to `EVM_DEFAULT_REPORT_ENCODER` (`{ encoderName: 'evm', signingAlgo: 'ecdsa', hashingAlgo: 'keccak256' }`)

**Returns:**

A `ReportRequestJson` object ready to pass to `runtime.report()`.

**Usage:**

```typescript
import { prepareReportRequest, type Runtime } from "@chainlink/cre-sdk"
import { encodeFunctionData } from "viem"
import { MyContractABI } from "./abi"

// Encode the function call data
const callData = encodeFunctionData({
  abi: MyContractABI,
  functionName: "updateValue",
  args: [42n],
})

// Generate a signed report using the helper (simplest approach)
const report = runtime.report(prepareReportRequest(callData)).result()

// The helper automatically sets:
// - encodedPayload: hexToBase64(callData)
// - encoderName: "evm"
// - signingAlgo: "ecdsa"
// - hashingAlgo: "keccak256"
```

**Equivalent manual approach:**

```typescript
import { hexToBase64, type Runtime } from "@chainlink/cre-sdk"

// Without the helper, you must specify all parameters manually
const report = runtime
  .report({
    encodedPayload: hexToBase64(callData),
    encoderName: "evm",
    signingAlgo: "ecdsa",
    hashingAlgo: "keccak256",
  })
  .result()
```

> **TIP: When to use this helper**
>
> Use `prepareReportRequest()` for all EVM write operations to reduce boilerplate and ensure consistent encoding parameters. It's particularly useful in workflows with multiple write operations, as it eliminates repetitive configuration.

***

### `LAST_FINALIZED_BLOCK_NUMBER`

A constant representing the last finalized block number for use in `callContract()` and similar methods.

```typescript
const LAST_FINALIZED_BLOCK_NUMBER = {
  absVal: Buffer.from([3]).toString("base64"), // 3 for finalized block
  sign: "-1",
}
```

**Usage:**

```typescript
import { LAST_FINALIZED_BLOCK_NUMBER } from "@chainlink/cre-sdk"

const contractCall = evmClient
  .callContract(runtime, {
    call: encodeCallMsg({ from: zeroAddress, to: contractAddress, data: callData }),
    blockNumber: LAST_FINALIZED_BLOCK_NUMBER,
  })
  .result()
```

***

### `LATEST_BLOCK_NUMBER`

A constant representing the latest mined block number.

```typescript
const LATEST_BLOCK_NUMBER = {
  absVal: Buffer.from([2]).toString("base64"), // 2 for the latest block
  sign: "-1",
}
```

## Chain Selectors

A **chain selector** is a unique identifier for a blockchain network used throughout the CRE platform. In TypeScript, you work with chain selectors primarily through the `getNetwork()` helper function.

> **NOTE: Chain Selector lookup**
>
> The `getNetwork()` function provides a type-safe way to look up network information by chain selector name. This
> returns an object containing the numeric chain selector (as a `bigint`) along with other network metadata.

### Using `getNetwork()`

The recommended way to work with chain selectors in TypeScript:

```typescript
import { getNetwork } from "@chainlink/cre-sdk"

const network = getNetwork({
  chainFamily: "evm",
  chainSelectorName: "ethereum-testnet-sepolia",
})

if (!network) {
  throw new Error("Network not found")
}

// Access the numeric chain selector (bigint)
const evmClient = new EVMClient(network.chainSelector.selector)
// network.chainSelector.selector is 16015286601757825753n (bigint)
```

### Supported networks

The `EVMClient` class includes a static `SUPPORTED_CHAINS` constant with all available chain selectors:

```typescript
EVMClient.SUPPORTED_CHAINS
// Returns:
// {
//   'avalanche-mainnet': 6433500567565415381n,
//   'avalanche-testnet-fuji': 14767482510784806043n,
//   'ethereum-testnet-sepolia': 16015286601757825753n,
//   // ... and more
// }
```

### Chain selector reference

This table shows the chain selector names and their numeric IDs. In your configuration files (`project.yaml`, `config.staging.json`, `config.production.json`, etc.), you always use the **String Name**. The numeric ID is used internally by the SDK and is returned by the `getNetwork()` helper function.

> **NOTE: Related resources**
>
> - **Forwarder addresses**: For network-specific forwarder contract addresses, see [Forwarder Directory](/cre/guides/workflow/using-evm-client/forwarder-directory)

- **RPC configuration**: For configuring RPC endpoints in `project.yaml`, see [Project Configuration](/cre/reference/project-configuration)

| Chain                   | String Name                           | Numeric ID           |
| ----------------------- | ------------------------------------- | -------------------- |
| Apechain Curtis         | apechain-testnet-curtis               | 9900119385908781505  |
| Arc Testnet             | arc-testnet                           | 3034092155422581607  |
| Arbitrum One            | ethereum-mainnet-arbitrum-1           | 4949039107694359620  |
| Arbitrum Sepolia        | ethereum-testnet-sepolia-arbitrum-1   | 3478487238524512106  |
| Avalanche Mainnet       | avalanche-mainnet                     | 6433500567565415381  |
| Avalanche Fuji          | avalanche-testnet-fuji                | 14767482510784806043 |
| Base Mainnet            | ethereum-mainnet-base-1               | 15971525489660198786 |
| Base Sepolia            | ethereum-testnet-sepolia-base-1       | 10344971235874465080 |
| BNB Chain Mainnet       | binance\_smart\_chain-mainnet         | 11344663589394136015 |
| BNB Chain Testnet       | binance\_smart\_chain-testnet         | 13264668187771770619 |
| Ethereum Mainnet        | ethereum-mainnet                      | 5009297550715157269  |
| Ethereum Sepolia        | ethereum-testnet-sepolia              | 16015286601757825753 |
| Hyperliquid Testnet     | hyperliquid-testnet                   | 4286062357653186312  |
| Ink Sepolia             | ink-testnet-sepolia                   | 9763904284804119144  |
| Jovay Mainnet           | jovay-mainnet                         | 1523760397290643893  |
| Jovay Testnet           | jovay-testnet                         | 945045181441419236   |
| Linea Sepolia           | ethereum-testnet-sepolia-linea-1      | 5719461335882077547  |
| OP Mainnet              | ethereum-mainnet-optimism-1           | 3734403246176062136  |
| OP Sepolia              | ethereum-testnet-sepolia-optimism-1   | 5224473277236331295  |
| Pharos Atlantic Testnet | pharos-atlantic-testnet               | 16098325658947243212 |
| Pharos Mainnet          | pharos-mainnet                        | 7801139999541420232  |
| Plasma Testnet          | plasma-testnet                        | 3967220077692964309  |
| Polygon Mainnet         | polygon-mainnet                       | 4051577828743386545  |
| Polygon Amoy            | polygon-testnet-amoy                  | 16281711391670634445 |
| World Chain Mainnet     | ethereum-mainnet-worldchain-1         | 2049429975587534727  |
| World Chain Sepolia     | ethereum-testnet-sepolia-worldchain-1 | 5299555114858065850  |
| ZKSync Era              | ethereum-mainnet-zksync-1             | 1562403441176082196  |
| ZKSync Era Sepolia      | ethereum-testnet-sepolia-zksync-1     | 6898391096552792247  |

### Usage in configuration files

**In your `project.yaml` file (RPC configuration):**

```yaml
local-simulation:
  rpcs:
    - chain-name: ethereum-testnet-sepolia # String name for RPC endpoint
      url: https://your-rpc-url.com
```

**In your workflow's `config.json` file (workflow-specific settings):**

Your workflow configuration can include chain selector names as part of your custom config structure. For example:

```json
{
  "schedule": "*/30 * * * * *",
  "evms": [
    {
      "storageAddress": "0x1234...",
      "chainName": "ethereum-testnet-sepolia" // Use string name in your config
    }
  ]
}
```

**In your workflow TypeScript code:**

```typescript
// Recommended: Use getNetwork() with the string name from your config
const network = getNetwork({
  chainFamily: "evm",
  chainSelectorName: config.evms[0].chainName, // Read from your config
})

if (!network) {
  throw new Error(`Network not found: ${config.evms[0].chainName}`)
}

const evmClient = new EVMClient(network.chainSelector.selector)
```