# Fetching Accounts

### Account definitions <a href="#account-definitions" id="account-definitions"></a>

Umi defines an account with serialized data as an `RpcAccount`. It contains information from the account header — i.e. the SOL on the account, the program owner, etc. — and the account's public key and serialized data.

```
type RpcAccount = AccountHeader & {
  publicKey: PublicKey;
  data: Uint8Array;
};
```

It also defines a `MaybeRpcAccount` type that represents an `RpcAccount` that may or may exist. When the account does not exist, it keeps track of its public key so that, in a list of accounts, we know which public key was not found.

```
type MaybeRpcAccount =
  | ({ exists: true } & RpcAccount)
  | { exists: false; publicKey: PublicKey };
```

When dealing with `MaybeRpcAccount`s, you may use the `assertAccountExists` helper method to assert that an account exists and fail otherwise.

```
assertAccountExists(myMaybeAccount);
// From now on, we know myMaybeAccount is an RpcAccount.
```

Last but not least, it provides a generic `Account` type that directly exposes the deserialized data — represented as a generic type `T` — with two extra attributes: `publicKey` and `header`. This allows us to directly access the deserialized data without nested `data` attributes.

```
type Account<T extends object> = T & {
  publicKey: PublicKey;
  header: AccountHeader;
};
```

### Fetching RPC accounts <a href="#fetching-rpc-accounts" id="fetching-rpc-accounts"></a>

Now that we know how accounts are represented in Umi, let's see how we can fetch them.

First of all, we can fetch a single account using the `getAccount` method of the `RpcInterface`. This will return a `MaybeRpcAccount` instance since the account may or may not exist. As mentioned above, you may use the `assertAccountExists` function to ensure it does.

```
const myAccount = await umi.rpc.getAccount(myPublicKey);
assertAccountExists(myAccount);
```

Note that if you are only interested to know if an account exists at the given address, you may use the `accountExists` method instead.

```
const accountExists = await umi.rpc.accountExists(myPublicKey);
```

If you need to fetch multiple accounts at once, you may use the `getAccounts` method instead. This will return a list of `MaybeRpcAccount`s, one for each public key you passed in.

```
const myAccounts = await umi.rpc.getAccounts(myPublicKeys);
```

Finally, the `getProgramAccounts` method can be used to fetch all accounts from a given program that match a given set of filters. This method returns a list of `RpcAccount` directly since it will only return accounts that exist. Refer to the following [Get Program Account documentation](https://solanacookbook.com/guides/get-program-accounts.html) to learn more about filters and data slicing.

```
// Fetch all accounts from a program.
const allProgramAccounts = await umi.rpc.getProgramAccounts(myProgramId);

// Fetch a slice of all accounts from a program.
const slicedProgramAccounts = await umi.rpc.getProgramAccounts(myProgramId, {
  dataSlice: { offset: 32, length: 8 },
});

// Fetch some accounts from a program that matches a given set of filters.
const filteredProgramAccounts = await umi.rpc.getProgramAccounts(myProgramId, {
  filters: [
    { dataSize: 42 },
    { memcmp: { offset: 0, bytes: new Uint8Array([1, 2, 3]) } },
  ],
});
```

Note that when fetching program accounts, you might be interested in [`GpaBuilder`s](https://developers.metaplex.com/umi/helpers#gpabuilders).

### Deserializing accounts <a href="#deserializing-accounts" id="deserializing-accounts"></a>

In order to turn a `RpcAccount` into a deserialized `Account<T>`, we simply need the `deserializeAccount` function and a `Serializer` that knows how to deserialize the account's data. You can read more about `Serializer`s in the [Serializers page](https://developers.metaplex.com/umi/serializers) but here's a quick example assuming the data is composed of two public keys and one `u64` number.

```
import { assertAccountExists, deserializeAccount } from '@metaplex-foundation/umi';
import { struct, publicKey, u64 } from '@metaplex-foundation/umi/serializers';

// Given an existing RPC account.
const myRpcAccount = await umi.rpc.getAccount(myPublicKey);
assertAccountExists(myRpcAccount);

// And an account data serializer.
const myDataSerializer = struct([
  ['source', publicKey()],
  ['destination', publicKey()],
  ['amount', u64()],
]);

// We can deserialize the account like so.
const myAccount = deserializeAccount(rawAccount, myDataSerializer);
// myAccount.source -> PublicKey
// myAccount.destination -> PublicKey
// myAccount.amount -> bigint
// myAccount.publicKey -> PublicKey
// myAccount.header -> AccountHeader
```

Note that, in practice, program libraries should provide account data serializers and helpers for you. Here's an example using a [Kinobi-generated library](https://developers.metaplex.com/umi/kinobi).

```
import { Metadata, deserializeMetadata, fetchMetadata, safeFetchMetadata } from '@metaplex-foundation/mpl-token-metadata';

// Deserializes a metadata account.
const metadata: Metadata = deserializeMetadata(umi, unparsedMetadataAccount);

// Fetch and deserialize a metadata account, fail if the account does not exist.
const metadata: Metadata = await fetchMetadata(umi, metadataPublicKey);

// Fetch and deserialize a metadata account, return null if the account does not exist.
const metadata: Metadata | null = await safeFetchMetadata(umi, metadataPublicKey);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://8bit-1.gitbook.io/solibrary/fetching-accounts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
