📘Read Client

The PreAuthorizedDebitReadClient component of the SDK is outlined in the interface found in our Github repo.

Instantiating a PreAuthorizedDebitReadClient

Mainnet

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

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:

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

Our IDL is already available as Typescript or JSON. If you'd like to directly fetch it on-chain, you can either run the script here or just use our SDK:

const OnchainIDL = await readClient.fetchIdlFromChain();

This should return the IDL found here.

Derive the Smart Delegate PDA

Derive the singleton SmartDelegate account's PDA details (public key and canonical bump):

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

Derive the Pre-Authorization PDA

Derive a PreAuthorization account's PDA details (public key and canonical bump) for a particular pair of token account and debit authority:

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 (returns null if no account found on-chain)

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 by providing it's public key (returns null if no account found on-chain)

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)

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 associated with a particular token account (you can specify one-time, recurring, or all types):

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)
}

Fetch all Pre-Authorizations associated with a debit authority

Fetch all PreAuthorization accounts associated with a particular debit authority (you can specify one-time, recurring, or all types):

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:

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):

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):

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:

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

Fetch the current owner of a token account

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):

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:

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):

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

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

Last updated