Sol.College

Full lesson

samui-wallet

Open Source wallet and toolbox for Solana builders ๐ŸŸ Cypherpunk Hackathon winner

What it does

From the project README:

If you're interested in contributing to Samui, please read our contributing docs before submitting a pull request.
Original
samui-build/samui-wallet
SuperStack fork
Blockchains/samui-wallet @ 6fc3250
Stars
167
Last push (original)
2026-10-25
Languages
TypeScript, MDX, CSS, HTML, JavaScript, Handlebars
Detected stack
@solana/kit
Categories
Wallets & IdentityInfrastructure & Tooling
Licence
MIT
Homepage
https://samui.build

Architecture

860 source files. By extension: .ts ร—447, .tsx ร—413.

Top-level directorySource files
packages810
apps31
examples11
(root)5
turbo3

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/samui-wallet/. 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.

samui-build/samui-wallet ยท packages/feature-tools/src/tools-routes.tsx L1โ€“24 @ 6fc3250 ยท MIT ยท original
import { useAccountActive } from '@workspace/db-react/use-account-active'import { useAccountGetTransactionSigner } from '@workspace/db-react/use-account-get-transaction-signer'import { useNetworkActive } from '@workspace/db-react/use-network-active'import { lazy } from 'react'import { useRoutes } from 'react-router'import { ToolsUiLayout } from './ui/tools-ui-layout.tsx' const ToolsFeatureAirdrop = lazy(() => import('./tools-feature-airdrop.tsx'))const ToolsFeatureCreateToken = lazy(() => import('./tools-feature-create-token.tsx'))const ToolsFeatureMintToken = lazy(() => import('./tools-feature-mint-token.tsx'))const ToolsFeatureStake = lazy(() => import('./tools-feature-stake.tsx'))const ToolsFeatureTransactionInspector = lazy(() => import('./tools-feature-transaction-inspector.tsx')) export default function ToolsRoutes() {  const account = useAccountActive()  const network = useNetworkActive()  const getTransactionSigner = useAccountGetTransactionSigner({ account })  return useRoutes([    {      children: [        { element: <ToolsFeatureAirdrop account={account} network={network} />, index: true },        { element: <ToolsFeatureAirdrop account={account} network={network} />, path: 'airdrop' },        {          element: (
  1. Line 10 const ToolsFeatureMintToken = lazy(() => import('./tools-feature-mint-token.tsx')): Mints new tokens. The mint authority must sign.
  2. Line 11 const ToolsFeatureStake = lazy(() => import('./tools-feature-stake.tsx')): Touches staking state: the amount locked and when it was locked.
samui-build/samui-wallet ยท packages/feature-tools/src/tools-feature-stake.tsx L121โ€“144 @ 6fc3250 ยท MIT ยท original
  const stakeAccount = accounts.find((item) => item.pubkey.toString() === address)   if (!stakeAccount) {    return <UiEmpty description="Stake account not found for the active wallet." />  }   return (    <ToolsUiStakeAccountDetail      account={stakeAccount}      actions={actions}      authority={authority}      close={async () => {        const closed = await actions.close(stakeAccount)        if (closed) {          navigate('/tools/stake/accounts')        }      }}    />  )} function ToolsFeatureStakeCreate({  address,  getTransactionSigner,
  1. Line 132 close={async () => {: Closes the account at the end of the instruction and refunds its lamports.
  2. Line 135 navigate('/tools/stake/accounts'): Touches staking state: the amount locked and when it was locked.
samui-build/samui-wallet ยท packages/feature-tools/src/ui/tools-ui-stake-account-detail.tsx L25โ€“48 @ 6fc3250 ยท MIT ยท original
  authority: Address  close: () => Promise<void>}) {  return (    <div className="space-y-4">      <div className="flex items-center justify-between gap-4">        <div className="flex items-center gap-2">          <UiBackButton aria-label="Back to stake accounts" to="/tools/stake/accounts" />          <div>            <div className="text-muted-foreground text-sm">Stake account</div>            <ExplorerUiLinkAddress address={account.pubkey} basePath="/explorer" />          </div>        </div>        <div className="flex items-center gap-2">          <Badge variant={getStakeAccountBadgeVariant(account)}>{getStakeAccountStatus(account)}</Badge>          <ToolsUiStakeAccountAction account={account} actions={actions} authority={authority} close={close} />        </div>      </div>      <Table>        <TableBody>          <ToolsUiStakeAccountDetailRow label="Balance" value={`${lamportsToSol(account.lamports)} SOL`} />          <ToolsUiStakeAccountDetailRow label="Delegated stake" value={`${formatStakeSol(account)} SOL`} />          <ToolsUiStakeAccountDetailRow label="Validator" value={<ToolsUiStakeValidatorLink account={account} />} />          <ToolsUiStakeAccountDetailRow
  1. Line 32 <UiBackButton aria-label="Back to stake accounts" to="/tools/stake/accounts" />: Touches staking state: the amount locked and when it was locked.
  2. Line 40 <ToolsUiStakeAccountAction account={account} actions={actions} authority={authority} close: Closes the account at the end of the instruction and refunds its lamports.
samui-build/samui-wallet ยท packages/solana-client/src/create-transfer-instructions-spl.ts L1โ€“24 @ 6fc3250 ยท MIT ยท original
import {  type Address,  assertIsAddress,  assertIsTransactionSigner,  type Instruction,  type TransactionSigner,} from '@solana/kit'import { findAssociatedTokenPda, getTransferCheckedInstruction, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token'import { createGetOrCreateAtaInstruction } from './create-get-or-create-ata-instruction.ts'import type { TransferRecipient } from './transfer-recipient.ts' interface CreateTransferInstructionsSplOptions {  decimals: number  mint: Address  recipients: TransferRecipient[]  source?: TransactionSigner  tokenProgram?: Address  transactionSigner: TransactionSigner} export async function createTransferInstructionsSpl({  decimals,  transactionSigner,  mint,
  1. Line 8 import { findAssociatedTokenPda, getTransferCheckedInstruction, TOKEN_PROGRAM_ADDRESS } fr: A checked token transfer, which also verifies the mint and decimals.
  2. Line 21 export async function createTransferInstructionsSpl({: An SPL token transfer through the Token Program.

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
.npm run devturbo run dev
.npm run buildturbo run build
.npm run testvitest run
.npm run lintbiome check --error-on-warnings
packages/backgroundnpm run testvitest run
packages/db-reactnpm run testvitest run
packages/uinpm run testvitest run
packages/dbnpm run testvitest run
packages/solana-clientnpm run testvitest run
packages/vault-reactnpm run testvitest run
packages/keypairnpm run testvitest run
packages/vaultnpm run testvitest run
packages/feature-portfolionpm run testvitest run
examples/basicnpm run devvite
examples/basicnpm run buildtsc -b && vite build
apps/apinpm run devwrangler dev

What you could build from it