> ## Documentation Index
> Fetch the complete documentation index at: https://docs.initia.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Querying Data

The InitiaJS SDK offers a powerful `RESTClient` that simplifies the process of
querying data from both the Initia L1 and rollups. This client encapsulates
various endpoints and methods into user-friendly helper functions, organized
under sub-categories of the `rest` client based on their corresponding Cosmos
SDK modules.

In this tutorial, you'll explore several examples demonstrating how to leverage
these helper functions to retrieve key data points efficiently using the SDK.

For demonstration purposes, assume that all of these examples are implemented in
a file named `src/query.ts`.

## Querying Account Balance

To query the balance of an account, you can use the `balance` function from the
`bank` module. This function takes in an address and returns the balance of the
account.

First, make the necessary imports and initialize the `RESTClient`.

```ts theme={null}
import { RESTClient, Coin } from '@initia/initia.js'

const restClient = new RESTClient('https://rest.testnet.initia.xyz', {
  chainId: 'initiation-2',
  gasPrices: '0.015uinit', // default gas prices
  gasAdjustment: '2.0', // default gas adjustment for fee estimation
})
```

<Note>
  Adjust gasPrices and gasAdjustment according to current
  [network](/resources/developer/initia-l1) conditions for optimal transaction
  processing.
</Note>

Next, create a function to query the balance of an account. This function will
take in an address and return the balance of the account.

Note that the response from the query is paginated, so you need to handle the
pagination properly in the function. Specifically, responses that are paginated
will return a `next_key` in the pagination object, which you can use to get the
next page of results. Then keep looping through the results until you have all
the pages, which you will know is the case when `next_key` is `null`.

```ts theme={null}
async function queryBalance(address: string) {
  let allCoins: Coin[] = []
  let nextKey: string | null = null

  do {
    const [coins, pagination] = await restClient.bank.balance(address, {
      'pagination.key': nextKey || undefined,
    })
    allCoins = [...allCoins, ...coins]
    nextKey = pagination.next_key || null
  } while (nextKey)

  console.log(`${address} has:`)
  allCoins.forEach((coin: Coin) => {
    console.log(`- ${coin.amount.toString()} ${coin.denom}`)
  })
}
```

You can then call the function with an address to query the balance of the
account.

```ts theme={null}
queryBalance('init1w4cqq6udjqtvl5xx0x6gjeyzgwtze8c05kysnu')
```

If successful, you should see an output similar to the following:

```sh theme={null}
init1w4cqq6udjqtvl5xx0x6gjeyzgwtze8c05kysnu has:
- 721662 uinit
- 1000000 uinit
```

## Complete Example

```ts src/query.ts theme={null}
import { RESTClient, Coin } from '@initia/initia.js'

const restClient = new RESTClient('https://rest.testnet.initia.xyz')

async function queryBalance(address: string) {
  let allCoins: Coin[] = []
  let nextKey: string | null = null

  do {
    const [coins, pagination] = await restClient.bank.balance(address, {
      'pagination.key': nextKey || undefined,
    })
    allCoins = [...allCoins, ...coins]
    nextKey = pagination.next_key || null
  } while (nextKey)

  console.log(`${address} has:`)
  allCoins.forEach((coin: Coin) => {
    console.log(`- ${coin.amount.toString()} ${coin.denom}`)
  })
}

queryBalance('init1w4cqq6udjqtvl5xx0x6gjeyzgwtze8c05kysnu')
```

## VM-Agnostic Queries

VM-agnostic queries are queries that can be used across all VMs.

* `balance()` : query the balance of an account

```typescript theme={null}
const balances = await restClient.bank.balance(
  'init14l3c2vxrdvu6y0sqykppey930s4kufsvt97aeu',
)
```

* `blockInfo()`: query the block information

```typescript theme={null}
const blockInfo = await restClient.tendermint.blockInfo(10000) // If no height is given, the latest block is returned.
```

* `txInfo()`: query the transaction information

```typescript theme={null}
const txInfo = await restClient.tx.txInfo(
  '6DFEE8E4BFC38341E8AADBD74A23588D8DE94FA38052CB5721DDA780A24F8B1D',
)
```

* `price()`: query the oracle price

```typescript theme={null}
const currencyPair = new CurrencyPair('BTC', 'USD')
const price = await restClient.oracle.price(currencyPair)
```

## VM-Specific Queries

## MoveVM

* `viewFunction()`: query the move contract view functions

```typescript theme={null}
// `object.move`
//
// #[view]
// public fun owner<T: key>(object: Object<T>): address acquires ObjectCore {
//     ...
// }

const res = await restClient.move.viewFunction(
  '0x1', // owner of the module
  'object', // name of the module
  'owner', // function name
  ['0x1::object::ObjectCore'], // type arguments
  [
    bcs
      .object()
      .serialize(
        '0xc4f0b3c2300c99b0d7717ce43cd76821407a34c79587542919876a8c241a2f94',
      )
      .toBase64(),
  ], // arguments
)
```

* `viewJSON()`: query the move contract view functions with JSON arguments

```typescript theme={null}
const res = await restClient.move.viewJSON(
  '0x1', // owner of the module
  'object', // name of the module
  'owner', // function name
  ['0x1::object::ObjectCore'], // type arguments
  [`"0xc4f0b3c2300c99b0d7717ce43cd76821407a34c79587542919876a8c241a2f94"`], // arguments
)
```

* `resources()`: query the move contract resources

```typescript theme={null}
const resources = await restClient.move.resources('0x1')
const resource = await restClient.move.resource('0x1', '0x1::code::ModuleStore')
```

* `modules()`: query the move contract modules

```typescript theme={null}
const modules = await restClient.move.module('0x1')
const module = await restClient.move.module('0x1', 'object')
```

* `tableInfo()`: query the move contract table info

```typescript theme={null}
const tableHandle =
  '0xc8c40eef193fc150fcb54264419bd3e39339c2ee8ba5834aed7826a9841cfb53'
const entryKeyBytes = 'A0vD7ATVOvfCWo1T7H8Pz2MOt5k6rvsScYEGgXe0QDw='

const tableInfo = await restClient.move.tableInfo(tableHandle)
const tableEntries = await restClient.move.tableEntries(tableHandle)
const tableEntry = await restClient.move.tableEntry(tableHandle, entryKeyBytes)
```

## WasmVM

* `contractInfo()`: query the wasm contract info

```typescript theme={null}
const contractInfo = await restClient.wasm.contractInfo(
  'init14mv62l7x4ducykg0crfa9a22egf8yrltmxzy84zn0wqgmr496jqs5z7k0c',
)
const contracts = await restClient.wasm.contractsByCode(1)
```

* `smartContractState()`: query the wasm smart contract state

```typescript theme={null}
const contractState = await restClient.wasm.smartContractState(
  'init1jue5rlc9dkurt3etr57duutqu7prchqrk2mes2227m52kkrual3qdrydg6', // contract address
  Buffer.from(
    JSON.stringify({
      // query data
      get_stage_info: {
        stage: 1,
      },
    }),
  ).toString('base64'),
)
const allContractStates = await restClient.wasm.allContractState(
  'init14mv62l7x4ducykg0crfa9a22egf8yrltmxzy84zn0wqgmr496jqs5z7k0c',
)
```

## EVM

* `call()`: query the evm contract

```typescript theme={null}
const contractInfo = JSON.parse(
  fs
    .readFileSync(
      '../solidity/evm-example/artifacts/contracts/example.sol/example.json', // path of build response
    )
    .toString(),
)
const contract = new ethers.Contract(contractAddress, contractInfo.abi)

const res = await restClient.evm.call(
  'init1jvxywa6dmdxumr9nhdez838af06f9v42w0rd26', // sender
  '0x16e999092BF37913a3eff185949997b6f7bd698c', // contract_addr
  contract.interface
    .encodeFunctionData(
      'getPoints',
      [2, 0, 10], // hex encoded execution input bytes
    )
    .slice(2),
  false, // whether to return the trace
)
```
