> For the complete documentation index, see [llms.txt](https://docs.seabed.so/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seabed.so/open-source-primitives/pre-authorized-debit-v1/typescript-sdk/read-client.md).

# Read Client

The `PreAuthorizedDebitReadClient` component of the SDK is outlined in the interface found in our [Github repo](https://github.com/seabed-labs/pre-authorized-debit/blob/main/sdk/pre-authorized-debit-v1/src/read/interface/index.ts).

## Instantiating a `PreAuthorizedDebitReadClient`

### Mainnet

```typescript
import { clusterApiUrl, Connection } from "@solana/web3.js";
import { PreAuthorizedDebitReadClientImpl } from "@seabed-labs/pre-authorized-debit";

// You can use any connection object you'd like, this is just an example
const connection = new Connection(clusterApiUrl("mainnet-beta"));

const readClient = PreAuthorizedDebitReadClientImpl.mainnet(connection);
```

### Devnet

```typescript
import { clusterApiUrl, Connection } from "@solana/web3.js";
import { PreAuthorizedDebitReadClientImpl } from "@seabed-labs/pre-authorized-debit";

// You can use any connection object you'd like, this is just an example
const connection = new Connection(clusterApiUrl("devnet"));

const readClient = PreAuthorizedDebitReadClientImpl.devnet(connection);
```

### Custom

Point the read client to a custom deployment on any cluster:

```typescript
import { clusterApiUrl, Connection } from "@solana/web3.js";
import { PreAuthorizedDebitReadClientImpl } from "@seabed-labs/pre-authorized-debit";

const connection = new Connection(/* your connection args */);
const CUSTOM_PAD_PROGRAM_ID = /* your custom program ID */;

const readClient = PreAuthorizedDebitReadClientImpl.custom(
  connection,
  CUSTOM_PAD_PROGRAM_ID
);
```

## Supported Methods

The read client supports the following methods:

* [Fetch IDL from chain](#fetch-idl-from-chain)
* [Derive the Smart Delegate PDA](#derive-the-smart-delegate-pda)
* [Derive the Pre-Authorization PDA](#derive-the-pre-authorization-pda)
* [Fetch the Smart Delegate account](#fetch-the-smart-delegate-account)
* [Fetch a Pre-Authorization account](#fetch-a-pre-authorization-account)
* [Fetch all Pre-Authorizations associated with a token account](#fetch-all-pre-authorizations-associated-with-a-token-account)
* [Fetch all Pre-Authorizations associated with a debit authority](#fetch-all-pre-authorizations-associated-with-a-debit-authority)
* [Check if amount can be debited against a pre-authorization](#check-if-amount-can-be-debited-against-a-pre-authorization)
* [Fetch maximum debit amount for a Pre-Authorization](#fetch-maximum-debit-amount-for-a-pre-authorization)
* [Fetch the token program ID for a token account](#fetch-the-token-program-id-for-a-token-account)
* [Fetch the current owner of a token account](#fetch-the-current-owner-of-a-token-account)
* [Fetch the current delegation of a token account](#fetch-the-current-delegation-of-a-token-account)
* [Fetch the current owner of a Pre-Authorization's token account](#fetch-the-current-owner-of-a-pre-authorizations-token-account)
* [Fetch the current delegation of a Pre-Authorization's token account](#fetch-the-current-delegation-of-a-pre-authorizations-token-account)

### Fetch IDL from chain

Our IDL is already available as [Typescript ](https://github.com/seabed-labs/pre-authorized-debit/blob/main/sdk/pre-authorized-debit-v1/src/pre_authorized_debit_v1.ts)or [JSON](/open-source-primitives/pre-authorized-debit-v1/program/anchor-idl.md#json-idl). If you'd like to directly fetch it on-chain, you can either run the script [here](/open-source-primitives/pre-authorized-debit-v1/program/anchor-idl.md#on-chain-idl) or just use our SDK:

```typescript
const OnchainIDL = await readClient.fetchIdlFromChain();
```

This should return the IDL found [here](https://explorer.solana.com/address/PadV1i1My8wazb6vi37UJ2s1yBDkFN5MYivYN6XgaaR/anchor-program).

### Derive the Smart Delegate PDA

Derive the singleton [`SmartDelegate` account](/open-source-primitives/pre-authorized-debit-v1/program/account-model/smart-delegate.md)'s PDA details (public key and canonical bump):

```typescript
const smartDelegatePDA = readClient.getSmartDelegatePDA();
const { publicKey, bump } = smartDelegatePDA;
```

### Derive the Pre-Authorization PDA

Derive a [`PreAuthorization` account](/open-source-primitives/pre-authorized-debit-v1/program/account-model/pre-authorization.md)'s PDA details (public key and canonical bump) for a particular pair of token account and debit authority:

```typescript
const tokenAccountPubkey = new PublicKey(/* Any token account pubkey */);
const debitAuthorityPubkey = new PublicKey(/* Any pubkey */);

const preAuthorizationPDA = readClient.derivePreAuthorizationPDA(
  tokenAccountPubkey,
  debitAuthorityPubkey
);
const { publicKey, bump } = preAuthorizationPDA;
```

### Fetch the Smart Delegate account

Fetch the singleton [`SmartDelegate` account](/open-source-primitives/pre-authorized-debit-v1/program/account-model/smart-delegate.md) (returns `null` if no account found on-chain)

```typescript
const smartDelegateProgramAccount = await readClient.fetchSmartDelegate();
const {
  publicKey, // PublicKey
  account, // SmartDelegateAccount
} = smartDelegateProgramAccount;

const {
  bump, // number (on-chain type: u8)
} = account;
```

### Fetch a Pre Authorization account

Fetch the [`PreAuthorization` account](/open-source-primitives/pre-authorized-debit-v1/program/account-model/pre-authorization.md) by providing it's public key (returns `null` if no account found on-chain)

```typescript
const preAuthorizationProgramAccount = await readClient.fetchPreAuthorization({
  publicKey: // public key for the account
});

const {
  publicKey, // PublicKey
  account, // PreAuthorizationAccount
} = preAuthorizationProgramAccount;

const {
  bump, // number (on-chain type: u8)
  tokenAccount, // PublicKey,
  debitAuthority, // PublicKey,
  activationUnixTimestamp, // bigint (on-chain i64)
  paused, // boolean
  variant, // PreAuthorizationVariantOneTime | PreAuthorizationVariantRecurring
} = account;

if (variant.type === "oneTime") {
  const {
    amountAuthorized, // bigint (on-chain u64)
    amountDebited, // bigint (on-chain u64)
    expiryUnixTimestamp, // bigint (on-chain i64)
  } = variant;
} else if (variant.type === "recurring") {
  const {
    recurringAmountAuthorized, // bigint (on-chain u64)
    repeatFrequencySeconds, // bigint (on-chain u64)
    resetEveryCycle, // boolean
    numCycles, // number | null (on-chain Option<u64>)
    amountDebitedTotal, // bigint (on-chain u64)
    amountDebitedLastCycle, // bigint (on-chain u64)
    lastDebitedCycle, // bigint (on-chain u64)
  } = variant;
}
```

Fetch it by providing the token account and debit authority instead (returns `null` if no account found on-chain)

```typescript
const preAuthorizationProgramAccount = await readClient.fetchPreAuthorization({
  tokenAccount: // token account pubkey,
  debitAuthority: // debit authority pubkey,
});

// ... (same as previous variant)
```

### Fetch all Pre-Authorizations associated with a token account

Fetch all [`PreAuthorization` accounts](/open-source-primitives/pre-authorized-debit-v1/program/account-model/pre-authorization.md) associated with a particular token account (you can specify one-time, recurring, or all types):

{% code fullWidth="false" %}

```typescript
const tokenAccount: PublicKey = // token account pubkey;
const type = "all";

const preAuthAccounts = await readClient.fetchPreAuthorizationsForTokenAccount(
  tokenAccount, // pubkey
  type, // "oneTime" or "recurring" or "all"
);

for (const account of preAuthAccounts) {
  // ... (access them similar to `fetchPreAuthorization` above)
}
```

{% endcode %}

### Fetch all Pre-Authorizations associated with a debit authority

Fetch all [`PreAuthorization` accounts](/open-source-primitives/pre-authorized-debit-v1/program/account-model/pre-authorization.md) associated with a particular debit authority (you can specify one-time, recurring, or all types):

```typescript
const debitAuthority: PublicKey = // debit authority pubkey;
const type = "all";

const preAuthAccounts = await readClient.fetchPreAuthorizationsForDebitAuthority(
  debitAuthority, // pubkey
  type, // "oneTime" or "recurring" or "all"
);

for (const account of preAuthAccounts) {
  // ... (access them similar to `fetchPreAuthorization` above)
}
```

### Fetch maximum debit amount for a Pre-Authorization

Fetch the maximum possible amount that can be debited by the debit authority for a given pre-authorization:

```typescript
const tokenAccount: PublicKey = // token account pubkey
const debitAuthority: PublicKey = // debit authority pubkey

const maxDebitAmount = await readClient.fetchMaxDebitAmount({
  tokenAccount,
  debitAuthority,
});
```

### Check if amount can be debited against a pre-authorization

Check whether a debit will go through given a pre-authorization pubkey (using the current solana validator time):

```typescript
const res = await readClient.checkDebitAmount({
  preAuthorization: // pre-auth pubkey,
  requestedDebitAmount: // amount to debit (bigint),
  txFeePayer: // the lamports fee payer pubkey for the tx,
  destinationTokenAccount: // optional - defaults to ATA of debitAuthority,
});

if (!res.successful) {
  const { reason } = res;
}
```

Check whether a debit will go through given the token account and debit authority pubkeys (using the current solana validator time):

```typescript
const res = await readClient.checkDebitAmount({
  tokenAccount: // token account pubkey,
  debitAuthority: // debit authority pubkey,
  requestedDebitAmount: // amount to debit (bigint),
  txFeePayer: // the lamports fee payer pubkey for the tx,
  destinationTokenAccount: // optional - defaults to ATA of debitAuthority,
});

if (!res.successful) {
  const { reason } = res;
}
```

### Fetch the token program ID for a token account

Fetch the token program ID (Token or Token2022) for a given token account:

```typescript
const tokenAccount: PublicKey = // token account pubkey
const tokenProgramId = await readClient.fetchTokenProgramIdForTokenAccount(
  tokenAccount
);
```

### Fetch the current owner of a token account

```typescript
const tokenAccount: PublicKey = // token account pubkey
const tokenAccountOwner = await readClient.fetchCurrentOwnerOfTokenAccount(
  tokenAccount
);
```

### Fetch the current delegation of a token account

Fetch the current delegate and delegated amount of a token account (returns null if no delegate or delegated amount is 0):

```typescript
const tokenAccount: PublicKey = // token account pubkey
const delegation = await readClient.fetchCurrentDelegationOfTokenAccount(
  tokenAccount
);

const {
  delegate, // PublicKey
  delegatedAmount, // bigint (on-chain u64)
} = delegation;
```

### Fetch the current owner of a Pre-Authorization's token account

Fetch the current owner of a token account given the pre-authorization public key:

```typescript
const preAuth: PublicKey = // pre-authorization pubkey
const tokenAccountOwner = await readClient.fetchCurrentOwnerOfPreAuthTokenAccount(
  preAuth
);
```

### Fetch the current delegation of a Pre-Authorization's token account

Fetch the current delegate and delegated amount of a token account given the pre-authorization public key (returns null if no delegate or delegated amount is 0):

```typescript
const preAuth: PublicKey = // pre-authorization pubkey
const delegation = await readClient.fetchCurrentDelegationOfPreAuthTokenAccount(
  preAuth
);

const {
  delegate, // PublicKey
  delegatedAmount, // bigint (on-chain u64)
} = delegation;
```
