Sol.College

Full lesson

pay

CLI for Agentic payments (x402, MPP, AP2).

What it does

From the project README:

The missing payment layer for HTTP — x402 & MPP payment challenges with user-authorized stablecoin signing.
Original
solana-foundation/pay
SuperStack fork
Blockchains/pay @ e22d0af
Stars
1,800
Last push (original)
2026-11-02
Languages
Rust, TypeScript, CSS, Shell, Python, JavaScript
Detected stack
@solana/kitNext.jsSolana Pay
Categories
AI & AgentsPayments
Licence
MIT
Homepage
https://pay.sh/docs

Architecture

414 source files. By extension: .rs ×277, .ts ×75, .tsx ×56, .js ×5, .jsx ×1.

Top-level directorySource files
rust278
typescript100
web-ui36

Dapp: deploying

This fork is queued for its own live dapp on Sol.College, with a Devnet/Mainnet switch. It appears here, at /dapps/pay/, once it is deployed and checked on devnet. Until then, 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.

solana-foundation/pay · typescript/packages/solana-pay/core/example/index.ts L61–84 @ e22d0af · MIT · original
console.log('Parsed amount:', parsed.amount?.toString()); // 3. Wallet creates transfer instructions and sendsconst instructions = await wallet.pay.createTransfer({    recipient: parsed.recipient,    amount: parsed.amount!,    splToken: parsed.splToken,    reference: parsed.reference,    memo: parsed.memo,}); // 4. Wallet sends — planner/executor handles blockhash, signing, and submissionconst result = await wallet.sendTransaction(instructions);console.log('Transaction sent:', result); // ── Back to merchant ─────────────────────────────────────────────── // 5. Merchant finds the transaction by referenceconst found = await merchant.pay.findReference(reference);console.log('Found signature:', found.signature); // 6. Merchant validates the transferawait merchant.pay.validateTransfer(found.signature, {    recipient,
  1. Line 73 const result = await wallet.sendTransaction(instructions);: Submits the signed transaction to the cluster.
  2. Line 79 const found = await merchant.pay.findReference(reference);: Finds or validates the on-chain payment by its reference key.
solana-foundation/pay · typescript/packages/solana-pay/core/src/client.ts L13–36 @ e22d0af · MIT · original
    /** Optional RPC subscriptions config (e.g. custom WebSocket URL for localhost). */    rpcSubscriptionsConfig?: DefaultRpcSubscriptionsChannelConfig<string>;} /** The type returned by {@link createMerchantClient}. */export type MerchantClient = ReturnType<typeof createMerchantClient>; /** * Creates a merchant-side Solana Pay client with RPC and the merchant plugin. * No payer required — merchants only encode URLs, generate QR codes, and * read from the network to find/validate payments. * * @example * ```ts * const merchant = createMerchantClient({ *   rpcUrl: 'https://api.mainnet-beta.solana.com', * }); * * const url = merchant.pay.encodeURL({ recipient, amount: 1.5 }); * const found = await merchant.pay.findReference(reference); * await merchant.pay.validateTransfer(found.signature, { recipient, amount: 1.5 }); * ``` */export function createMerchantClient(config: MerchantClientConfig) {
  1. Line 31 * const url = merchant.pay.encodeURL({ recipient, amount: 1.5 });: Encodes a Solana Pay request URL.
  2. Line 32 * const found = await merchant.pay.findReference(reference);: Finds or validates the on-chain payment by its reference key.
solana-foundation/pay · typescript/packages/solana-pay/core/src/index.ts L1–13 @ e22d0af · MIT · original
export * from './constants.js';export * from './client.js';export * from './createQR.js';export * from './createTransfer.js';export * from './encodeURL.js';export * from './fetchTransaction.js';export * from './findReference.js';export * from './parseURL.js';export * from './types.js';export * from './validateTransfer.js';export * from './watchReference.js';export * from './plugins/merchant.js';export * from './plugins/wallet.js';
  1. Line 5 export * from './encodeURL.js';: Encodes a Solana Pay request URL.
  2. Line 7 export * from './findReference.js';: Finds or validates the on-chain payment by its reference key.
solana-foundation/pay · typescript/packages/solana-pay/core/src/plugins/merchant.ts L13–36 @ e22d0af · MIT · original
    createTransactionMessage,    getBase64EncodedWireTransaction,    pipe,    setTransactionMessageConfig,    setTransactionMessageFeePayer,} from '@solana/kit';import type { ClientWithRpc, ClientWithRpcSubscriptions } from '@solana/plugin-interfaces';import type { LogsNotificationsApi } from '@solana/rpc-subscriptions-api'; import { createQR, createQROptions } from '../createQR.js';import type { TransactionRequestURLFields, TransferRequestURLFields } from '../encodeURL.js';import { encodeURL } from '../encodeURL.js';import type { ConfirmedSignatureInfo, FindReferenceOptions } from '../findReference.js';import { findReference } from '../findReference.js';import type { Finality, Reference, TransferFields } from '../types.js';import { validateTransfer } from '../validateTransfer.js';import type { WatchReferenceOptions, WatchReferenceResult } from '../watchReference.js';import { watchReference } from '../watchReference.js'; type MerchantRpcApi = GetSignaturesForAddressApi & GetTransactionApi; type MerchantRpcSubscriptionsApi = LogsNotificationsApi; type MerchantCompatibleClient = ClientWithRpc<MerchantRpcApi> & ClientWithRpcSubscriptions<MerchantRpcSubscriptionsApi>;
  1. Line 23 import type { TransactionRequestURLFields, TransferRequestURLFields } from '../encodeURL.j: Encodes a Solana Pay request URL.
  2. Line 25 import type { ConfirmedSignatureInfo, FindReferenceOptions } from '../findReference.js';: Finds or validates the on-chain payment by its reference key.

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
rust/examplenpm run devtsx watch server.ts
rust/examplenpm run starttsx server.ts
web-uinpm run devconcurrently "tsx watch api/index.ts" "vite"
web-uinpm run starttsx api/index.ts
web-uinpm run buildvite build && tsc --noEmit
web-uinpm run testvitest run

What you could build from it

Used in lessons