add-skill
Install a pinned skill extension on demand (/add-skill <id>), or list core packs and extensions
Decode a token mint's extensions and live authorities, and flag integration risks
> /plugin marketplace add solanabr/ai-kit > /plugin install solana-ai-kit@stbr
How it fires
How this command gets triggered: by you, by Claude, or both.
/inspect-mintContext preview
What this command does when you run it.
Decode a token mint's extensions and live authorities, and flag integration risks
description: "Decode a token mint's extensions and live authorities, and flag integration risks"
Inspect the mint in $ARGUMENTS: what it takes to integrate, and who can still change it. Read-only. Extension meanings and per-extension rules: [token-extensions](../skills/token-extensions/SKILL.md); what an integrator has to handle: [Reading an unknown mint](../skills/token-extensions/SKILL.md#reading-an-unknown-mint) and [Token accounts and transfers](../skills/token-extensions/SKILL.md#token-accounts-and-transfers); venue policy and the pre-launch checks: [programs.md, Before launch](../skills/token-extensions/references/programs.md#before-launch).
| Input | Notes | |---|---| | `mint` | Required. | | `rpc` or `cluster` | Default mainnet. Prefer the project's provider (`HELIUS_API_KEY` in `.env`: `https://mainnet.helius-rpc.com/?api-key=<key>`); public RPCs rate-limit. | | `for` | `integrate` (default: a program, frontend or venue accepting the mint) or `issue` (an issuer reviewing their own mint before launch). |
Don't read extensions from RPC `jsonParsed` or `spl-token display`. Agave RPC nodes before 4.2 decode with `spl-token-2022-interface` 2.x, and for a mint that carries PermissionedBurn they return no `extensions` field at all, hiding a permanent delegate or hook on the same mint. `spl-token` 5.5.0 and a `--locked` 5.6.1 build use the same decoder. Decode with `@solana-program/token-2022` 0.19 on Kit 8 instead: from the project root if it already depends on both, otherwise from a scratch directory.
mkdir -p "$HOME/.cache/solana-ai-kit/inspect-mint" && cd "$HOME/.cache/solana-ai-kit/inspect-mint" && npm init -y >/dev/null && npm i -q '@solana/kit@^8.3' '@solana-program/token-2022@^0.19'
The scratch directory lives under `$HOME/.cache`, not `$TMPDIR`, because the run needs mainnet RPC and Node's `fetch` ignores the sandbox's proxy — so under Claude Code the run goes outside the sandbox, where `$TMPDIR` names a different directory than it did during the install, and the script would not be found. `$HOME` is the same on both sides, and `~/.cache` is in the kit's sandbox `allowWrite`.
`@solana-program/token-2022` 0.19 peers `@solana/kit` `^8.3`. A workspace pinned to an older kit major keeps its pin — run from the scratch directory instead of moving it.
Write this block to `inspect-mint.mjs` in the directory you installed into — the kit ships no such file, so it has to be written before the run line below resolves (adjust that path if you installed at the project root).
// node inspect-mint.mjs <mint> [rpc-url]: decode a mint from raw bytes (RPC jsonParsed can drop extensions)
import { address, createSolanaRpc, fetchEncodedAccount, unwrapOption } from '@solana/kit';
import { decodeMint, findExtraAccountMetaListPda, TOKEN_PROGRAM_ADDRESS, TOKEN_2022_PROGRAM_ADDRESS } from '@solana-program/token-2022';
const [mintArg, url = 'https://api.mainnet-beta.solana.com'] = process.argv.slice(2);
const rpc = createSolanaRpc(url);
const mint = address(mintArg);
const account = await fetchEncodedAccount(rpc, mint);
if (!account.exists) throw new Error('account not found on this cluster');
const is2022 = account.programAddress === TOKEN_2022_PROGRAM_ADDRESS;
if (!is2022 && account.programAddress !== TOKEN_PROGRAM_ADDRESS) throw new Error(`owned by ${account.programAddress}, not a token program`);
const len = account.data.length; // 82 = classic mint; extended mints carry account type 1 at byte 165 and are never 355 (multisig) bytes
if (len !== 82 && (len <= 165 || len === 355 || account.data[165] !== 1)) throw new Error('not a mint (token account or multisig)');
const { data } = decodeMint(account);
const extensions = unwrapOption(data.extensions) ?? [];
const hook = extensions.find((e) => e.__kind === 'TransferHook');
let hookMetaList = null;
if (hook && hook.programId !== '11111111111111111111111111111111') {
const [pda] = await findExtraAccountMetaListPda({ mint }, { programAddress: hook.programId });
hookMetaList = { address: pda, exists: (await fetchEncodedAccount(rpc, pda)).exists };
}
const { epoch } = await rpc.getEpochInfo().send();
const plain = (_, v) => typeof v === 'bigint' ? v.toString() : v instanceof Map ? Object.fromEntries(v)
: v?.__option ? (v.__option === 'Some' ? v.value : null) : v;
console.log(JSON.stringify({ mint, program: is2022 ? 'Token-2022' : 'SPL Token', epoch, ...data, extensions, hookMetaList }, plain, 2));node "$HOME/.cache/solana-ai-kit/inspect-mint/inspect-mint.mjs" <MINT> <RPC_URL>
Kit's `__kind` names differ from the Rust ones — `ScaledUiAmountConfig`, `PausableConfig`, `ConfidentialTransferFee` ([Reading an unknown mint](../skills/token-extensions/SKILL.md#reading-an-unknown-mint)). Report the extension under the name the user will meet in their own tool.
Claude Code, set up to ship on Solana. Not programs alone — the whole lifecycle: validating the idea, building the program and the app around it, shipping it, and the launch and growth work that follows.
Install a pinned skill extension on demand (/add-skill <id>), or list core packs and extensions
Audit infra security: secrets, deps, CI/CD, webhooks, AI/skill files
Audit Solana program code for exploitable bugs and write a findings report
Compare per-instruction CU with the stored baseline to catch regressions
Build the web client (Next.js, Vite, React) and check env, types and bundle
Build Solana programs (Anchor, Pinocchio, native), incl. verifiable builds