mark_key_used
Stored in dapp/app/lib/mcp/tools/mark-key-used.ts, this tool lets the chatbot flag a colored-key NFT as “used” for the active chain. It is JWT-gated to ensure only authenticated users can consume their access.
Handler Behavior
- JWT extraction — Uses the injected
__jwt.addressto determine which wallet owns the key, falling back tojwt,sub, or session fields if needed. - Prisma model —
getTokenModel(prisma)selects the chain-aware table (Sepolia, Mainnet, RitoNet) viaprismaNetworkUtils. - Atomic update — Calls
updateManywithused: falsein thewhereclause, ensuring concurrent calls cannot mark the same token twice. - Verification — After the update, fetches the record again to confirm
used=trueand returns metadata (token ID, chain name, usedAt timestamp).
// dapp/app/lib/mcp/tools/mark-key-used.ts
const tool: Tool<Params> = {
name: 'mark_key_used',
requiresJwt: true,
inputSchema: InputSchema,
async handler(params) {
const { address, tokenId } = extractJwt(params);
if (!address) fail('Not signed in');
if (!Number.isFinite(tokenId)) fail('Missing or invalid tokenId');
const Token = getTokenModel(prisma);
const updated = await Token.updateMany({ where: { tokenId, used: false }, data: { used: true, usedBy: address, usedAt: new Date() } });
if (!updated.count) return errorResultShape('Token already used or not found');
const record = await Token.findUnique({ where: { tokenId } });
const text = textResult(`Marked key #${tokenId} as used on ${formatChainName(canonicalChain)}`);
const json = jsonResult({ tokenId, chainName: formatChainName(canonicalChain), address, usedAt: record?.usedAt });
return { content: [...text.content, ...json.content] };
},
};Presenter
dapp/components/chatBot/ToolActivity/catalog/presenters/mark_key_used.presenter.ts emphasizes the token details:
| Status | Output |
|---|---|
| pending | Marking Key as Used (no body text). |
| success | Key #123 on Sepolia by 0xABCD… at 03/14/2025 09:15:00 (using formatUsedAtForUser). |
| error | Detects wallet/auth issues and suggests reconnecting when JWT data is missing. |
Notes
The tool does not mark the NFT as “used” on-chain. Instead, it modifies the access-control row inside Prisma so the rest of the dapp can recognize who has consumed their gated content.