Full reference for the TokenForge issuer dashboard
The TokenForge dashboard is a Next.js 16 application that sits between issuers and the Solana blockchain. It provides a no-code interface for deploying and managing security tokens using the canonical SSTS programs.
| Route | Description |
|---|---|
| /dashboard | Overview with KPI cards, recent activity, quick actions |
| /dashboard/tokens | Token list with search and filters |
| /dashboard/tokens/create | 3-step wizard: Details → Metadata → Deploy |
| /dashboard/tokens/[mint] | Token detail with transaction history and policy tabs |
| /dashboard/tokens/[mint]/mint | Mint tokens form |
| /dashboard/tokens/[mint]/transfer | Transfer with FAMP gating toggle |
| /dashboard/tokens/[mint]/policy | Full FAMP policy management |
| /dashboard/policies | Policy list derived from tokens |
| /dashboard/policies/[mint] | Per-token policy management |
| /dashboard/distributions | Distribution list |
| /dashboard/distributions/create | Create escrow + Claim (tabs) |
| /dashboard/distributions/[id] | Distribution detail with claim history |
| /dashboard/activity | Full transaction log with search and type filter |
| /dashboard/settings | Network configuration and RPC endpoint |
| Route | Method | Purpose |
|---|---|---|
| /api/stats | GET | Aggregate KPI counts |
| /api/tokens | GET/POST | List tokens / create DB record |
| /api/tokens/[mint] | GET/PATCH | Single token detail / status update |
| /api/transactions | GET/POST | List transactions / record |
| /api/test-create-token | POST | Deploy SSTS token on-chain + persist |
| /api/mint-tokens | POST | Mint tokens via server-side keypair |
| /api/transfer-tokens | POST | Transfer with optional FAMP enforcement |
| /api/famp-policy | POST | FAMP CRUD: 6 actions |
| /api/distribution | POST | Create escrow + Claim distribution |
| /api/init-vc-transfer | POST | Init VerificationConfig for transfer |
| /api/r3-upload | POST | Upload metadata JSON to Cloudflare R2 |
Creates a canonical SSTS security token on Solana devnet.
{ "name": "My Token", "symbol": "MST", "decimals": 6, "uri": "https://..." }Mints tokens to a destination ATA (auto-creates if missing).
{ "mintAddress": "...", "destination": "...", "amount": "1000" }Transfers tokens with optional FAMP policy enforcement.
{
"mintAddress": "...",
"source": "...",
"recipient": "...",
"amount": "100",
"enforceFamp": true
}Full FAMP policy CRUD. Supports 6 actions.
| Action | Extra Params | Description |
|---|---|---|
| create | allowlistMode (bool) | Create FAMP policy |
| addToAllowlist | wallet (base58) | Add wallet to allowlist |
| removeFromAllowlist | wallet | Remove from allowlist |
| addToBlocklist | wallet | Add to blocklist |
| removeFromBlocklist | wallet | Remove from blocklist |
| getPolicy | none | Read policy state from chain |
| Instruction | Discriminator |
|---|---|
| createPolicy | [27, 81, 33, 27, 196, 103, 246, 53] |
| addToAllowlist | [149, 143, 78, 134, 241, 244, 7, 56] |
| removeFromAllowlist | [45, 46, 214, 56, 189, 77, 242, 227] |
| addToBlocklist | [201, 138, 75, 216, 252, 201, 26, 106] |
| removeFromBlocklist | [132, 125, 30, 120, 139, 22, 210, 90] |
Create escrow (disc 20) and Claim distribution (disc 21).
{
"action": "create",
"mintAddress": "...",
"merkleRoot": "0x...64hexchars...",
"escrowTokenAccount": "...",
"actionId": 0
}{
"action": "claim",
"mintAddress": "...",
"claimantAddress": "...",
"amount": "1000",
"merkleRoot": "0x...",
"actionId": 0,
"leafIndex": 0,
"proofs": ["0x...", "0x..."]
}PostgreSQL via Drizzle ORM — 6 tables.
| Item | Icon | Sub-items |
|---|---|---|
| Overview | LayoutDashboard | — |
| Tokens | Coins | All Tokens, Create Token |
| Policies | ShieldCheck | — |
| Distributions | Send | — |
| Activity | Activity | — |
| Settings | Settings | — |
Color-coded badge using CVA with 15 variants.
Truncated Solana address with copy-to-clipboard and tooltip.
| Function | Description |
|---|---|
| deriveMintAuthorityPda | MintAuthority PDA for the token |
| deriveFreezeAuthorityPda | FreezeAuthority PDA |
| deriveVerificationConfigPda | VerificationConfig PDA per discriminator |
| deriveFampPolicyPda | FAMP PolicyAccount PDA |
| deriveProofAccountPda | ProofAccount PDA for distributions |
| deriveRateAccountPda | RateAccount PDA for splits/conversions |
| derivePermanentDelegatePda | PermanentDelegate PDA |
| deriveTransferHookPda | TransferHook PDA |
| deriveExtraAccountMetasPda | ExtraAccountMetas PDA |
| Variable | Required | Description |
|---|---|---|
| DATABASE_URL | Yes | PostgreSQL connection string |
| TEST_WALLET_KEYPAIR | Yes | Server-side signing keypair (base64 or JSON array) |
| R2_ACCOUNT_ID | No | Cloudflare account ID (for metadata upload) |
| R2_ACCESS_KEY_ID | No | R2 API access key |
| R2_SECRET_ACCESS_KEY | No | R2 API secret key |
| R2_BUCKET_NAME | No | R2 bucket name |
| R2_PUBLIC_URL | No | Public URL for bucket |
cd dashboard
npm install
cp .env.example .env.local
# Edit .env.local with DATABASE_URL and TEST_WALLET_KEYPAIR
npm run db:migrate
npm run dev| Script | Purpose |
|---|---|
| dev | Development server (turbopack) |
| build | Production build |
| start | Production server |
| lint | ESLint check |
| db:generate | Generate Drizzle migration |
| db:migrate | Apply migrations |
| db:studio | Drizzle ORM GUI |