Skip to content

Token Service

The TokenService provides methods to interact with token accounts on Solana. In the NosanaClient, it's configured for the NOS token and accessible via client.nos.

Get All Token Holders

Fetch all accounts holding NOS tokens using a single RPC call.

ts
import type { TokenAccountWithBalance } from '@nosana/kit';
// Get all holders (excludes zero balance accounts by default)
const 
holders
: TokenAccountWithBalance[] = await
client
.
nos
.
getAllTokenHolders
();
console
.
log
(`Found ${
holders
.
length
} NOS token holders`);
holders
.
forEach
((
holder
) => {
console
.
log
(`${
holder
.
owner
}: ${
holder
.
uiAmount
} NOS`);
}); // Include accounts with zero balance const
allAccounts
: TokenAccountWithBalance[] = await
client
.
nos
.
getAllTokenHolders
({
includeZeroBalance
: true });
console
.
log
(`Total accounts: ${
allAccounts
.
length
}`);
// Exclude PDA accounts (smart contract-owned token accounts) const
userAccounts
: TokenAccountWithBalance[] = await
client
.
nos
.
getAllTokenHolders
({
excludePdaAccounts
: true });
console
.
log
(`User-owned accounts: ${
userAccounts
.
length
}`);

Get Token Account for Address

Retrieve the NOS token account for a specific owner.

ts
import { 
address
} from '@nosana/kit';
import type { TokenAccountWithBalance } from '@nosana/kit'; const
account
: TokenAccountWithBalance | null = await
client
.
nos
.
getTokenAccountForAddress
(
address
('owner-address'));
if (
account
) {
console
.
log
('Token Account:',
account
.
pubkey
);
console
.
log
('Owner:',
account
.
owner
);
console
.
log
('Balance:',
account
.
uiAmount
, 'NOS');
console
.
log
('Raw Amount:',
account
.
amount
.
toString
());
console
.
log
('Decimals:',
account
.
decimals
);
} else {
console
.
log
('No NOS token account found');
}

Get Balance

Convenience method to get just the NOS balance for an address.

ts
import { 
address
} from '@nosana/kit';
const
balance
: number = await
client
.
nos
.
getBalance
(
address
('owner-address'));
console
.
log
(`Balance: ${
balance
} NOS`);
// Returns 0 if no token account exists

Transfer Tokens

Get instruction(s) to transfer SPL tokens. Returns either 1 or 2 instructions depending on whether the recipient's associated token account needs to be created.

ts
import { 
address
} from '@nosana/kit';
import type {
Instruction
} from '@solana/kit';
// Get transfer instruction(s) const
instructions
:
Instruction
[] = await
client
.
nos
.
transfer
({
to
:
address
('recipient-address'),
amount
: 1000000, // token base units (can be number or bigint)
// from is optional - uses wallet if not provided }); // Execute the transfer // instructions is a tuple: // - [TransferInstruction] when recipient ATA exists (1 instruction) // - [CreateAssociatedTokenIdempotentInstruction, TransferInstruction] when ATA needs creation (2 instructions) await
client
.
solana
.
buildSignAndSend
(
instructions
);

The function automatically:

  • finds the sender's associated token account;
  • finds the recipient's associated token account;
  • creates the recipient's ATA if it doesn't exist (returns 2 instructions: create ATA + transfer);
  • returns only the transfer instruction if the recipient's ATA already exists (returns 1 instruction).

Type Definitions

ts
import type { Address, TokenAccount, TokenAccountWithBalance } from '@nosana/kit';

interface TokenAccount {
  pubkey: Address;
  owner: Address;
  mint: Address;
  amount: bigint;
  decimals: number;
}

interface TokenAccountWithBalance extends TokenAccount {
  uiAmount: number; // Balance with decimals applied
}