Sol.College

Full lesson

zalary

Confidential payroll on Solana: Token-2022 confidential transfer amounts, mint auditor keys, MoonPay off-ramp to NGN/INR/BRL

What it does

From the project README:

Cross-border contractor pay with Token-2022 confidential transfer amounts. Employees cash out to local currency in the same app.
Original
ajanaku1/zalary
SuperStack fork
Blockchains/zalary @ b4a3f12
Stars
0
Last push (original)
2026-07-21
Languages
TypeScript, CSS, HTML, JavaScript
Detected stack
@solana/kitweb3.js
Categories
PaymentsInfrastructure & Tooling
Licence
MIT
Homepage
https://zalary.vercel.app

Architecture

63 source files. By extension: .tsx ×34, .ts ×28, .js ×1.

Top-level directorySource files
app63

Dapp: devnet deploy pending

⏳ Devnet deploy pending — goes live when the devnet wallet is topped up. This fork's own dapp is not deployed yet, so there is no program address or transaction to show. It is queued in dapp-queue.txt; once devnet SOL is available it is deployed, exercised with real devnet transactions, and this section switches to the live dapp at /dapps/zalary/. Until then, the lesson and step-by-step guide below are complete, and you can run it locally with the commands below.

Key code, explained

Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.

ajanaku1/zalary · app/api/faucet.ts L49–72 @ b4a3f12 · MIT · original
    tx.add(      createAssociatedTokenAccountIdempotentInstruction(        faucet.publicKey,        recipientAta,        recipient,        ZUSDC_MINT,        TOKEN_2022_PROGRAM_ID,      ),    )    tx.add(      createMintToInstruction(        ZUSDC_MINT,        recipientAta,        faucet.publicKey,        AMOUNT_PER_REQUEST,        [],        TOKEN_2022_PROGRAM_ID,      ),    )     const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed')    tx.recentBlockhash = blockhash    tx.feePayer = faucet.publicKey    tx.sign(faucet)
  1. Line 55 TOKEN_2022_PROGRAM_ID,: Targets the Token-2022 program instead of the original Token Program.
  2. Line 59 createMintToInstruction(: Mints new tokens. The mint authority must sign.
  3. Line 69 const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed: Fetches a recent blockhash. Transactions expire if it gets too old.
ajanaku1/zalary · app/src/lib/send-plan.ts L85–108 @ b4a3f12 · MIT · original
  connection: Connection,  feePayer: PublicKey,  sendTransaction: SendTransactionFn,  instruction: Instruction,  extraSigners: Keypair[] = [],): Promise<string> {  return sendInstructionBatch(connection, feePayer, sendTransaction, [instruction], extraSigners)} export async function sendInstructionBatch(  connection: Connection,  feePayer: PublicKey,  sendTransaction: SendTransactionFn,  instructions: Instruction[],  extraSigners: Keypair[] = [],): Promise<string> {  const tx = new Transaction()  for (const ix of instructions) tx.add(kitIxToWeb3(ix))  tx.feePayer = feePayer  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed')  tx.recentBlockhash = blockhash   if (extraSigners.length > 0) {    tx.partialSign(...extraSigners)
  1. Line 87 sendTransaction: SendTransactionFn,: Submits the signed transaction to the cluster.
  2. Line 104 const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed: Fetches a recent blockhash. Transactions expire if it gets too old.
ajanaku1/zalary · app/src/lib/program.ts L1–24 @ b4a3f12 · MIT · original
import { Program, AnchorProvider, BN } from '@coral-xyz/anchor'import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, ComputeBudgetProgram, type Connection, type Transaction } from '@solana/web3.js'import { TOKEN_2022_PROGRAM_ID, createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddressSync } from '@solana/spl-token'import { IDL } from './zalary_idl'import { getPriorityFeeEstimate } from './helius-enhanced' // Poll signature status manually instead of using connection.confirmTransaction,// which relies on a WebSocket signatureSubscribe that some RPCs (Helius free tier,// public devnet) drop silently — leading to 30s/120s legacy timeouts.export async function pollConfirm(connection: Connection, sig: string, timeoutMs = 90_000): Promise<void> {  const start = Date.now()  while (Date.now() - start < timeoutMs) {    const { value } = await connection.getSignatureStatuses([sig])    const status = value[0]    if (status?.err) throw new Error(`On-chain failure: ${JSON.stringify(status.err)} (sig: ${sig})`)    if (status?.confirmationStatus === 'confirmed' || status?.confirmationStatus === 'finalized') return    await new Promise(r => setTimeout(r, 2000))  }  throw new Error(`Confirmation timed out after ${timeoutMs / 1000}s. Signature: ${sig}`)} export const PROGRAM_ID = new PublicKey('FGBieAeHERm7CJxtXsicQ7NaQ4FqsDixSwmMqKhovfpH') export type ZalaryProgram = Program<any>
  1. Line 2 import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, ComputeBudgetProgram, type Connecti: Sets the compute-unit limit or price (priority fee).
  2. Line 3 import { TOKEN_2022_PROGRAM_ID, createAssociatedTokenAccountIdempotentInstruction, getAsso: Targets the Token-2022 program instead of the original Token Program.
ajanaku1/zalary · app/src/lib/confidential.ts L133–156 @ b4a3f12 · MIT · original
    owner: asAddress(owner),    mint: asAddress(mint),    tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,  })  return ata} export function findTokenAtaSync(owner: PublicKey, mint: PublicKey): PublicKey {  return getAssociatedTokenAddressSync(mint, owner, false, TOKEN_2022_PROGRAM_ID)} export async function createConfidentialMint(params: {  connection: Connection  owner: PublicKey  signMessage: WalletSignMessage  sendTransaction: SendTransactionFn}): Promise<{ mint: string; signatures: string[] }> {  const { connection, owner, signMessage, sendTransaction } = params  // Kit's generateKeyPairSigner uses non-extractable CryptoKeys, so we co-sign  // with a web3.js Keypair instead (partialSign + wallet fee-payer).  const mintKeypair = Keypair.generate()  const payer = createAddressSigner(owner)  const mintAddr = asAddress(mintKeypair.publicKey)  const newMintSigner = {
  1. Line 141 return getAssociatedTokenAddressSync(mint, owner, false, TOKEN_2022_PROGRAM_ID): Targets the Token-2022 program instead of the original Token Program.
  2. Line 148 sendTransaction: SendTransactionFn: Submits the signed transaction to the cluster.

How to run, build and test

These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.

DirectoryCommandRuns
appnpm run devvite
appnpm run buildtsc -b && vite build
appnpm run linteslint .

What you could build from it