> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/reading-account-state/account-sync/typescript-sdk-reference.md).

# Account Sync TypeScript SDK reference

Reference for Account Sync in @triton-one/triton-sdk: connection modes, configuration, read semantics, tracked accounts, errors and the full API.

`@triton-one/triton-sdk` adds [Yellowstone Account Sync](/solana/reading-account-state/account-sync.md) to the `@solana/web3.js` `Connection`. Six account-read methods resolve from an in-memory buffer fed by a stream; every other method uses JSON-RPC as usual. For what Account Sync is and a first program, see the [overview](/solana/reading-account-state/account-sync.md).

{% tabs %}
{% tab title="npm" %}

```bash
npm install @triton-one/triton-sdk
```

{% endtab %}

{% tab title="pnpm" %}

```bash
pnpm add @triton-one/triton-sdk
```

{% endtab %}

{% tab title="Yarn" %}

```bash
yarn add @triton-one/triton-sdk
```

{% endtab %}
{% endtabs %}

The package is an ES module. It needs a runtime with global `fetch` or a browser build tool. It is built on `@solana/web3.js` 1.x (`^1.98.4`, installed as its dependency) and re-exports all of it, so use its `PublicKey` and other web3.js classes rather than ones from a separately installed web3.js 3.x.

## Connection modes

`new Connection(endpoint, config)` returns one of two classes:

| Second argument                                                        | Returns                                     |
| ---------------------------------------------------------------------- | ------------------------------------------- |
| Nothing, a commitment string, or web3.js options without `accountSync` | A plain web3.js `Connection` with no buffer |
| An object with `accountSync: undefined`                                | A plain web3.js `Connection`                |
| An object whose `accountSync` is set, including `accountSync: {}`      | An `AccountSyncConnection`                  |

{% hint style="warning" %}
`new Connection(endpoint, "finalized")` does **not** enable Account Sync. To set a commitment and enable it, write `new Connection(endpoint, { commitment: "finalized", accountSync: {} })`.
{% endhint %}

`AccountSyncConnection` has `addAccounts`, `removeAccounts`, `setAccounts`, `close` and `getLastTransportError`; a plain `Connection` doesn't. The exported `Connection` **type** is the web3.js type, so annotate variables with `AccountSyncConnection`, or let TypeScript infer the type from the constructor:

```ts
import { AccountSyncConnection, Connection } from "@triton-one/triton-sdk";

const connection: AccountSyncConnection = new Connection(endpoint, {
  accountSync: {},
});
```

In plain mode, web3.js options such as `fetch`, `fetchMiddleware`, `httpHeaders` and `wsEndpoint` go straight to web3.js. In Account Sync mode, inherited web3.js methods still use them, but the SDK's own RPC requests don't.

## Endpoints and tokens

* `endpoint` (the first constructor argument) is your Solana JSON-RPC URL. Inherited web3.js methods use it, and so does the SDK for initial values, cache misses and outage polling. The SDK's own requests send no custom headers, so put your token in the URL path: `https://<your-endpoint>.mainnet.rpcpool.com/<your-token>`.
* `endpoint` must start with `http:` or `https:`, or the constructor throws.
* `accountSync.subscriptionEndpoint` is the Account Sync stream URL. When you omit it, gRPC uses `endpoint` as is, and WebSocket uses `endpoint` with `http` changed to `ws` and `https` to `wss`.
* **gRPC:** the stream URL path must be empty or exactly `/<token>`. The SDK strips the token from the URL and sends it as `x-token` metadata.
* **gRPC:** a longer path in the stream URL, or a scheme other than `http`/`https` in `subscriptionEndpoint`, makes the stream fail to connect. The constructor doesn't throw: the error appears in `getLastTransportError()` while reads fall back to RPC.
* **WebSocket:** the SDK rewrites the path to `/<token>/YellowstoneAccountSyncService/ws`, taking the token from the last path segment.
* **WebSocket:** `subscriptionEndpoint` can start with `ws:` or `wss:`.

Both URLs must point at the same cluster. If RPC and the stream use different hosts, set `subscriptionEndpoint`:

```ts
import { AccountSyncTransports, Connection } from "@triton-one/triton-sdk";

const connection = new Connection("https://rpc.example.com/<RPC_TOKEN>", {
  accountSync: {
    transport: AccountSyncTransports.GRPC,
    subscriptionEndpoint: "https://stream.example.com/<STREAM_TOKEN>",
  },
});
```

## Configuration

All Account Sync options go under `accountSync`:

| Option                     | Type                                                       | Default                             | Meaning                                                                              |
| -------------------------- | ---------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------ |
| `transport`                | `AccountSyncTransports.WS` or `AccountSyncTransports.GRPC` | `WS`                                | Stream transport. Browsers use `WS`; `GRPC` isn't available.                         |
| `subscriptionEndpoint`     | `string`                                                   | Derived from `endpoint`             | Stream URL. JSON-RPC always uses `endpoint`.                                         |
| `commitment`               | `"processed"`, `"confirmed"` or `"finalized"`              | See below                           | Default commitment for reads and account-set methods.                                |
| `initialAccounts`          | Array of `string` or `PublicKey`                           | `[]`                                | Accounts pinned from startup.                                                        |
| `autoSubscribeOnMiss`      | `boolean`                                                  | `true`                              | Temporarily subscribe to an untracked account when a default-commitment read misses. |
| `missTimeoutMs`            | positive safe integer                                      | `5000`                              | Deadline for a read that misses the buffer.                                          |
| `rpcPollIntervalMs`        | positive safe integer                                      | `1000`                              | Interval between RPC polls of tracked accounts while the stream is down.             |
| `reconnectInitialDelayMs`  | positive safe integer                                      | `100`                               | First reconnect delay. Doubles after each failed attempt.                            |
| `reconnectMaxDelayMs`      | positive safe integer                                      | `5000`                              | Largest reconnect delay. Must be at least `reconnectInitialDelayMs`.                 |
| `connectTimeoutMs`         | positive safe integer                                      | `10000`                             | Limit for one WebSocket connection attempt. Not used by gRPC.                        |
| `closeTimeoutMs`           | positive safe integer                                      | `5000`                              | Limit for `close()`.                                                                 |
| `dynamicSubscriptionTtlMs` | positive safe integer                                      | `60000`                             | Idle lifetime of a temporary subscription.                                           |
| `grpc`                     | object                                                     | See [gRPC settings](#grpc-settings) | gRPC transport tuning. Requires `AccountSyncTransports.GRPC`.                        |

Times are milliseconds. A safe integer is a whole number that JavaScript can represent exactly (up to `Number.MAX_SAFE_INTEGER`). Zero, negative, fractional, `NaN` and out-of-range values throw in the constructor, as do invalid `initialAccounts` addresses.

`transport` is a TypeScript string enum. Pass `AccountSyncTransports.GRPC` or `AccountSyncTransports.WS`: the literals `"grpc"` and `"ws"` fail to type-check.

**Default commitment.** The SDK uses `accountSync.commitment` if set. Otherwise it uses the top-level `commitment` if that is `processed`, `confirmed` or `finalized`, and otherwise `confirmed`. Any other top-level value (such as `"max"`) silently becomes `confirmed`, while the same value passed to a read throws.

### gRPC settings

Set these under `accountSync.grpc`, with `transport: AccountSyncTransports.GRPC`:

| Option                         | Default             | Meaning                                              |
| ------------------------------ | ------------------- | ---------------------------------------------------- |
| `flowControlWindowBytes`       | `16777216` (16 MiB) | Fixed HTTP/2 receive window used by `@grpc/grpc-js`. |
| `maxReceiveMessageLengthBytes` | `16777216` (16 MiB) | Largest gRPC message the client accepts.             |
| `keepAliveIntervalMs`          | `30000`             | Time between keepalive pings.                        |
| `keepAliveTimeoutMs`           | `10000`             | Time allowed for a keepalive response.               |
| `keepAlivePermitWithoutCalls`  | `true`              | Send keepalive pings while no call is active.        |

Numbers must be positive safe integers. The Node.js constructor throws if you pass `grpc` with the WebSocket transport. The JavaScript gRPC transport doesn't support Zstd stream compression.

## Reading accounts

These six methods keep their web3.js signatures and result shapes: `getAccountInfo`, `getAccountInfoAndContext`, `getMultipleAccountsInfo`, `getMultipleAccountsInfoAndContext`, `getParsedAccountInfo` and `getMultipleParsedAccounts`.

### How a read resolves

1. If the buffer holds a suitable value, the read returns it with no RPC request.
2. Otherwise the SDK sends one `getMultipleAccounts` request containing every unresolved account in the call and, by default, starts a temporary subscription. It also waits for the stream. The first source to answer wins, including an RPC error.
3. If neither answers within `missTimeoutMs`, context and multiple-account methods reject with `AccountSyncReadTimeoutError`.

`null` means RPC confirmed the account doesn't exist, at the slot in `context.slot`. It never means a timeout or a failure. A missing account doesn't block the read until it appears.

### Context slot

A value from RPC carries the RPC response's context slot. A value from the stream carries the slot of that account's last update, which can lag the cluster when the account hasn't changed. For multiple-account reads, `context.slot` is the lowest slot among all results, including missing accounts. It doesn't mean the accounts came from one bank snapshot.

### Several accounts

Results stay in input order. Duplicate addresses get duplicate positions, and a missing account is `null` in its position.

```ts
const response = await connection.getMultipleAccountsInfoAndContext([
  addressA,
  addressB,
  addressA,
]);

console.log("Lowest slot:", response.context.slot);
console.log("Accounts:", response.value);
```

{% hint style="warning" %}
**Known limitation (verified on 0.1.0, 0.1.1 and 0.1.2):** the SDK fetches all of a call's unbuffered accounts in a single RPC request, and RPC nodes accept at most 100 accounts per `getMultipleAccounts` request. A call that needs more than 100 accounts from RPC can be rejected. Keep each multiple-account read to 100 addresses or fewer.
{% endhint %}

### `dataSlice`

```ts
const account = await connection.getAccountInfo(address, {
  dataSlice: { offset: 8, length: 32 },
});
```

This returns at most 32 bytes starting at byte 8. Both numbers must be non-negative safe integers. A zero length or an offset past the end returns an empty `Buffer`. The slice is applied locally: the stream still delivers, and the buffer still holds, the full account. Parsed methods ignore `dataSlice`.

### `minContextSlot`

```ts
const recentSlot = await connection.getSlot("finalized");

const response = await connection.getAccountInfoAndContext(address, {
  minContextSlot: recentSlot,
});
```

`minContextSlot` must be a non-negative safe integer. A buffered value older than it doesn't count, so the read goes to RPC, which receives the same `minContextSlot`. A node that hasn't reached that slot typically returns error `-32016`, which rejects the read immediately. Because an unchanged account keeps its last update slot, reads with a recent `minContextSlot` often go to RPC.

### Parsed accounts

`getParsedAccountInfo` and `getMultipleParsedAccounts` return `AccountInfo<Buffer | ParsedAccountData>`: `ParsedAccountData` when the parser can parse the account, and from version 0.1.1 the raw `Buffer` when it can't, for example an unsupported owner program or a System-owned account that isn't a nonce account. Check for `parsed` before you use it:

```ts
const response = await connection.getParsedAccountInfo(address);

if (response.value && "parsed" in response.value.data) {
  console.log("Parsed:", response.value.data.parsed);
}
```

* Parsing happens locally, on the full buffered account.
* If the parser doesn't support the account's owner program, behavior depends on the version. In 0.1.0 the read **rejects** with `WasmParserError` (for `getMultipleParsedAccounts`, one failure rejects the whole call). From 0.1.1, `getParsedAccountInfo` and `getMultipleParsedAccounts` return the raw data as a `Buffer` instead. Missing accounts are `null` in every version.
* Parsing an SPL token account needs its mint. The connection loads the mint through its own `getAccountInfo`. It caches the mint of an SPL Token account (256 entries, 5 minutes). Concurrent parses of an SPL Token account that need the same uncached mint share one fetch. From version 0.1.1 it doesn't cache Token-2022 mints. From version 0.1.1, if the mint request fails, the read rejects with the error from that call: an `Error` whose message starts `failed to get info about account <mint>`.
* From version 0.1.1, parsing a Token-2022 account also loads the Clock sysvar (`SysvarC1ock11111111111111111111111111111111`) through the same `getAccountInfo` and passes its Unix timestamp to the parser as `unixTimestamp`. If the Clock account is missing, the read rejects with `InvalidAccountDataError`.

### The `space` field

From version 0.1.1, reads return `space`: the full size of the buffered account, even when you use `dataSlice`. In version 0.1.0, `space` is not returned; use `data.length`, which is the size of the data you received (smaller than the account when you use `dataSlice`).

## Tracked accounts

A tracked account is one the stream sends updates for. Each is either pinned or temporary.

**Pinned** accounts stay tracked until you remove them or close the connection. Set them with `initialAccounts` or `addAccounts`. Adding an account that has a temporary subscription makes it pinned.

**Temporary** subscriptions are created when a read misses the buffer at the default commitment and `autoSubscribeOnMiss` is `true`, and always for reads at another commitment. One expires `dynamicSubscriptionTtlMs` (60 s) after the last read of that account finishes. Each read renews it.

**With `autoSubscribeOnMiss: false`,** a default-commitment read of an untracked account makes a one-time RPC request and returns the real account (or `null` if it doesn't exist). Nothing is subscribed and the value isn't kept.

**`removeAccounts`** drops the pin or temporary subscription, deletes the buffered value immediately and clears any cached mint for that address. A read already in progress can still finish through RPC, and a later read can create a new temporary subscription. Removing an untracked address isn't an error.

**`setAccounts`** makes its list the complete pinned set, removes every temporary subscription and deletes the buffered values of accounts that leave the set.

All three methods take an optional commitment, defaulting to the connection's Account Sync commitment, and settle once the change is recorded:

```ts
await connection.addAccounts([addressC, addressD]);
await connection.removeAccounts([addressA]);
await connection.setAccounts([addressB, addressC], "finalized");
```

Addresses can be strings or `PublicKey` values. Duplicates are ignored, and an invalid address throws before anything changes. The SDK sets no limit on the number of tracked accounts.

## Commitment levels

The SDK supports `processed`, `confirmed` and `finalized`. Each has its own stream, buffer and tracked set. The default commitment's stream opens when you construct the connection. A read or `addAccounts` at another commitment opens that commitment's stream, which closes again once it has no pinned or temporary accounts and no reads in progress. Override the commitment for one read with a string, as in `getAccountInfo(address, "processed")`, or with `{ commitment }`. Any other commitment name throws.

## Stream outages

When the stream drops, the SDK records the error, polls every tracked account over RPC every `rpcPollIntervalMs`, and reconnects with backoff from `reconnectInitialDelayMs` up to `reconnectMaxDelayMs`. After reconnecting, it resends the full tracked set, reloads the accounts over RPC and then stops polling. Reads keep working throughout.

## Errors and recovery

| Outcome                                                            | Meaning                                                                                                                                                    |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `null` value                                                       | RPC confirmed the account doesn't exist.                                                                                                                   |
| `AccountSyncReadTimeoutError`                                      | Neither the buffer nor RPC answered within `missTimeoutMs`.                                                                                                |
| `SolanaJSONRPCError`                                               | The RPC node returned an error, such as `-32016` for an unreached `minContextSlot`.                                                                        |
| `Error` with an HTTP status                                        | The RPC request failed at the HTTP level.                                                                                                                  |
| `WasmParserError`                                                  | The parser failed. In 0.1.0 this includes an unsupported program.                                                                                          |
| `Error` with a message starting `failed to get info about account` | `getAccountInfo` wraps any failure in this message, including a timeout or an RPC error. From 0.1.1 it also covers a failed mint request in a parsed read. |
| `Error`                                                            | Invalid input (address, commitment, `dataSlice`, `minContextSlot`), or the connection is closed.                                                           |

### Read timeouts

```ts
import { AccountSyncReadTimeoutError } from "@triton-one/triton-sdk";

try {
  const response = await connection.getAccountInfoAndContext(address);
  console.log(response.value);
} catch (error) {
  if (error instanceof AccountSyncReadTimeoutError) {
    console.error(error.accountId, error.commitment, error.timeoutMs);
    console.error("Minimum slot:", error.minContextSlot ?? "not set");
  } else {
    throw error;
  }
}
```

### RPC errors

```ts
import { SolanaJSONRPCError } from "@triton-one/triton-sdk";

try {
  await connection.getAccountInfoAndContext(address, {
    minContextSlot: requiredSlot,
  });
} catch (error) {
  if (error instanceof SolanaJSONRPCError && error.code === -32016) {
    console.error("The RPC node hasn't reached the requested slot yet");
  } else {
    throw error;
  }
}
```

`getAccountInfo` follows web3.js and wraps every failure in a new `Error` whose message names the account, so `instanceof` checks don't match. Use the context or multiple-account methods when you need the typed error.

### Background errors

```ts
const error = connection.getLastTransportError();

if (error) {
  console.warn("Account Sync background error:", error.message);
}
```

This returns the latest error from stream, polling, initial-value or reconnect work. It's never cleared, so a non-null value doesn't mean the connection is broken now. Use it for logs, not as a health check.

### Connect and close timeouts

A WebSocket attempt longer than `connectTimeoutMs` fails with an error named `AccountSyncConnectTimeoutError`. If shutdown takes longer than `closeTimeoutMs`, `close()` rejects with an error named `AccountSyncCloseTimeoutError`, and the connection is closed anyway. After `close()`, reads and most account-set calls reject with `account-sync connection is closed`. Calling `close()` again returns the same result.

{% hint style="warning" %}
**Known limitation (verified on 0.1.0, 0.1.1 and 0.1.2, Node.js):** calling `close()` while a WebSocket stream is still connecting can crash the process with an unhandled `WebSocket was closed before the connection was established` error. In Node.js, use the gRPC transport.
{% endhint %}

## Browser apps

Browser build tools pick the package's browser entry automatically. It uses the WebSocket transport and doesn't load gRPC code. Passing `AccountSyncTransports.GRPC` or `grpc` options throws in the constructor.

{% hint style="danger" %}
Anything you ship to a browser is public. Don't put a secret token in browser code. See [Auth and security](/security/authentication.md#allowed-origins-frontend) for browser access.
{% endhint %}

```ts
import {
  AccountSyncTransports,
  Connection,
  PublicKey,
} from "@triton-one/triton-sdk";

const address = new PublicKey("So11111111111111111111111111111111111111112");

const connection = new Connection("https://<your-browser-endpoint>", {
  accountSync: {
    transport: AccountSyncTransports.WS,
    initialAccounts: [address],
  },
});

async function showBalance(): Promise<void> {
  const response = await connection.getAccountInfoAndContext(address);
  const output = document.querySelector("#balance");
  if (output) {
    output.textContent = response.value
      ? `${response.value.lamports} lamports at slot ${response.context.slot}`
      : `Account missing at slot ${response.context.slot}`;
  }
}

void showBalance().catch(console.error);

window.addEventListener("pagehide", () => {
  void connection.close();
});
```

## Complete lifecycle example

`autoSubscribeOnMiss: false` keeps the tracked accounts to the explicit calls.

{% code title="lifecycle.mts" %}

```typescript
import {
  AccountSyncTransports,
  Connection,
  PublicKey,
} from "@triton-one/triton-sdk";

const endpoint = process.env.RPC_URL;
const subscriptionEndpoint = process.env.ACCOUNT_SYNC_URL;

if (!endpoint || !subscriptionEndpoint) {
  throw new Error("Set RPC_URL and ACCOUNT_SYNC_URL");
}

const address = new PublicKey("So11111111111111111111111111111111111111112");
const newAddress = new PublicKey("SysvarC1ock11111111111111111111111111111111");

const connection = new Connection(endpoint, {
  accountSync: {
    transport: AccountSyncTransports.GRPC,
    subscriptionEndpoint,
    commitment: "confirmed",
    autoSubscribeOnMiss: false,
  },
});

try {
  await connection.addAccounts([address]);

  const first = await connection.getAccountInfoAndContext(address);
  console.log("First read:", first);

  await connection.removeAccounts([address]);

  // Re-add it before the next read so it remains pinned.
  await connection.addAccounts([address]);

  const second = await connection.getAccountInfoAndContext(address);
  console.log("Read after re-add:", second);

  await connection.setAccounts([newAddress]);

  const third = await connection.getAccountInfoAndContext(newAddress);
  console.log("New account:", third);
} finally {
  await connection.close();
}
```

{% endcode %}

## Production guidance

* **Reuse one connection and close it on shutdown.** It owns streams, timers and retries, and an open connection keeps a Node.js process alive.
* **Size your RPC usage, not just the stream.** The SDK calls RPC for initial values, misses, reloads after set changes and reconnects, outage polling and mint lookups. These count against your [rate limits](/using-your-endpoint/rate-and-connection-limits.md) and are billed under your [plan](/account-and-billing/plans-and-billing.md).
* **Keep the tracked set stable.** Every change to a commitment's tracked set, including a temporary subscription starting or expiring, reloads all of that commitment's tracked accounts over RPC, in batches of 100. For large sets, pin the accounts you need and consider `autoSubscribeOnMiss: false`.
* **Watch memory and bandwidth.** The full data of every tracked account sits in process memory, and every update streams in full. Start with the default 16 MiB gRPC window, and test with realistic account sizes and update rates before you raise it or the message limit.
* **Keep up with the stream.** Triton closes a session whose server-side queue fills because the client can't consume updates fast enough. The SDK reconnects and polls in the meantime. Avoid short-lived function workers for a continuous stream.
* **Monitor read outcomes.** Track read errors, timeouts and latency. A successful read can come from RPC, so it doesn't prove the stream is healthy.

## Troubleshooting

### Why is my result `null`?

RPC confirmed the account didn't exist at the returned slot at that commitment. Check the address and commitment.

### Why did my read time out?

Neither the stream nor RPC answered within `missTimeoutMs`. Check both URLs, the token, RPC health and any `minContextSlot`. Raise the timeout if the read needs longer.

### Why was my minimum slot not reached?

The RPC node can return `-32016`, which rejects the read immediately. Use a slot the cluster has reached and a suitable commitment. A stream value carries the slot of the account's last update.

### Reads work, but is the stream connected?

Call `getLastTransportError()`. Reads can be served by RPC polling while the stream fails, for example because a gRPC URL has more than one path segment or the endpoint doesn't serve Account Sync.

### Why doesn't the WebSocket connect?

Check that:

* `endpoint` starts with `http:` or `https:`.
* The token is in the URL path when the endpoint needs one.
* Your endpoint serves the Account Sync WebSocket service.
* Any proxy in between allows WebSocket upgrades.
* In a browser, your page's origin is allowed for the endpoint.

Then call `getLastTransportError()` for the latest background error. The SDK can still be serving reads through RPC polling.

### Why does the browser say gRPC is unsupported?

Browsers can't use gRPC. Use `AccountSyncTransports.WS`. gRPC is available in Node.js.

### Why does `getLastTransportError()` return an error after recovery?

The SDK keeps the most recent background error and never clears it.

### Why won't my Node.js process exit?

Await `connection.close()`.

### Why didn't a removed account stay removed?

A later read created a new temporary subscription. Stop reading it on this connection, or set `autoSubscribeOnMiss: false`.

## Advanced account encoding

These helpers convert raw account values to Solana RPC encodings; most applications don't need them. They run in a WebAssembly module bundled with the package that loads on first use. Under Node.js it is read from disk; in a browser it is loaded as a static asset of the package. It makes no RPC calls.

| Encoding      | Output                                                                                                              |
| ------------- | ------------------------------------------------------------------------------------------------------------------- |
| `binary`      | A base58 string (legacy name).                                                                                      |
| `base58`      | A `[data, "base58"]` tuple.                                                                                         |
| `base64`      | A `[data, "base64"]` tuple.                                                                                         |
| `base64+zstd` | A `[data, "base64+zstd"]` tuple of zstd-compressed data.                                                            |
| `jsonParsed`  | Parsed data. When the account can't be parsed, 0.1.0 rejects and 0.1.1 and later return a `[data, "base64"]` tuple. |

```ts
import {
  accountInfoToEncodingInput,
  convertAccountData,
  encodeAccount,
} from "@triton-one/triton-sdk";

const base58Data = await convertAccountData("AQID", "base64", "base58");

const accountInfo = await connection.getAccountInfo(address);
if (accountInfo) {
  const encoded = await encodeAccount(
    accountInfoToEncodingInput(address, accountInfo),
    "base64",
  );
  console.log(base58Data, encoded.data, encoded.space);
}
```

### Functions

* `convertAccountData(input, from, to)` converts between raw encodings. It rejects `jsonParsed`.
* `encodeAccount(input, encoding, options?)` returns a `UiAccount` (`lamports`, `data`, `owner`, `executable`, `rentEpoch`, `space`). With `options.dataSlice`, `space` still reports the full size; slices don't apply to `jsonParsed`.
  * `options.unixTimestamp`: Unix time in seconds for `jsonParsed` parsers whose output depends on the time. Set it in `parseContext` or at the top level of `options`; the top-level value wins. It must be a safe integer.
* `parseJsonParsed(input, options?)` exists in version 0.1.0. It parses once with the context in `options.parseContext` (for example `splTokenMint: { pubkey, data }`) and never fetches data. Version 0.1.1 removed it: use `encodeAccount(input, "jsonParsed", { parseContext })`.
* `loadAccountEncodingWasm()` loads and initializes the bundled encoder. Repeated and concurrent calls share one initialization.
* `toWeb3JsParsedAccountInfo(account)` converts a `UiAccount` from `encodeAccount(input, "jsonParsed")` into a web3.js account with a `PublicKey` owner.
  * From 0.1.1 it returns `AccountInfo<Buffer | ParsedAccountData>`, and a `[data, "base64"]` tuple becomes a `Buffer`.
  * In 0.1.0 it returns `AccountInfo<ParsedAccountData>`.
  * It throws `UnsupportedEncodingError` when `data` is neither parsed data nor (from 0.1.1) a `[data, "base64"]` tuple.

### `AccountEncodingInput`

Use `accountInfoToEncodingInput` to build one from a web3.js account.

| Field        | Type                               | Notes                                               |
| ------------ | ---------------------------------- | --------------------------------------------------- |
| `pubkey`     | `string` or `PublicKey`            | Address of the account.                             |
| `owner`      | `string` or `PublicKey`            | Address of the program that owns the account.       |
| `lamports`   | `number`, `bigint` or `string`     | Unsigned 64-bit integer. A string must be decimal.  |
| `executable` | `boolean`                          | Whether the account contains an executable program. |
| `rentEpoch`  | `number`, `bigint` or `string`     | Unsigned 64-bit integer. A string must be decimal.  |
| `data`       | `Uint8Array`, `Buffer` or `string` | Raw account bytes, or a base64 string.              |

The SDK rejects numbers that aren't safe integers, negative values, values above the unsigned 64-bit maximum, invalid addresses and invalid base64.

### Errors

| Error                      | Meaning                                                                                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `UnsupportedEncodingError` | Unsupported encoding or conversion.                                                                                                              |
| `InvalidAccountDataError`  | Invalid account field, encoded value or option.                                                                                                  |
| `MissingParseContextError` | Parsing needs data you didn't supply.                                                                                                            |
| `WasmParserError`          | The parser failed. In 0.1.0 this includes an unsupported program; from 0.1.1, an unsupported program returns a `[data, "base64"]` tuple instead. |

## web3.js compatibility

To migrate, change the import, add `accountSync` to the constructor config, and call `close()` when you're done:

```diff
- import { Connection, PublicKey } from "@solana/web3.js";
+ import { Connection, PublicKey } from "@triton-one/triton-sdk";
```

Behavior differs from web3.js in the ways on this page: buffered values, temporary subscriptions, per-commitment streams, outage polling, typed timeout errors, parsed reads that reject instead of returning raw data (in 0.1.0; from 0.1.1 they return a `Buffer`), and `space` missing in version 0.1.0.

## Public API

```
new Connection(endpoint, commitmentOrConfig?)

connection.getAccountInfo(publicKey, commitmentOrConfig?)
connection.getAccountInfoAndContext(publicKey, commitmentOrConfig?)
connection.getParsedAccountInfo(publicKey, commitmentOrConfig?)
connection.getMultipleAccountsInfo(publicKeys, commitmentOrConfig?)
connection.getMultipleAccountsInfoAndContext(publicKeys, commitmentOrConfig?)
connection.getMultipleParsedAccounts(publicKeys, config?)

connection.addAccounts(accountIds, commitment?)
connection.removeAccounts(accountIds, commitment?)
connection.setAccounts(accountIds, commitment?)
connection.getLastTransportError()
connection.close()
```

**Values and classes:** `Connection`, `AccountSyncConnection`, `AccountSyncTransports`, `AccountSyncReadTimeoutError`, `AccountParseContextCache`, `ContextFetchError`, `InvalidAccountDataError`, `MissingParseContextError`, `UnsupportedEncodingError`, `WasmParserError`, `accountInfoToEncodingInput`, `bufferedAccountToEncodingInput`, `convertAccountData`, `encodeAccount`, `isBase64ZstdEncodingSupported`, `loadAccountEncodingWasm`, `parseJsonParsed` (version 0.1.0; removed in 0.1.1), `toWeb3JsParsedAccountInfo`, and everything from `@solana/web3.js`.

**Types (both builds):** `AccountSyncCommitment`, `AccountSyncOptions<TTransport>`, `AccountSyncReadTimeoutErrorOptions`, `BufferedAccountState`, and the encoding types `AccountDataEncoding`, `AccountEncodingInput`, `AccountEncodingOptions`, `AccountParseContext`, `AccountParseContextAccount`, `AccountParseContextCacheOptions`, `AccountParseContextFetcher`, `AccountParseContextMint`, `ConvertAccountDataOptions`, `EncodedAccountData` and `UiAccount`.

**Node.js build:** `GrpcTransportOptions`, `NodeAccountSyncConnectionConfig`, `NodeSubscriptionTransport`. **Browser build:** `BrowserAccountSyncConnectionConfig`, `BrowserSubscriptionTransport`.

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
