Skip to main content
Glama

generate_non_fungible_post_condition

Create mandatory NFT transfer post-conditions for SIP-009 tokens to ensure secure blockchain transactions by specifying ownership requirements.

Instructions

Generate a non-fungible token post-condition for SIP-009 NFTs. Post-conditions are MANDATORY for all NFT transfers.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assetNameYesThe NFT asset name (usually same as contract name)
conditionCodeYesThe condition type ('owns' or 'does_not_own')
contractAddressYesThe NFT contract address
contractNameYesThe NFT contract name
principalYesThe Stacks address for the post-condition
tokenIdYesThe NFT token ID

Implementation Reference

  • The complete tool object for 'generate_non_fungible_post_condition', including the execute handler that generates formatted documentation, TypeScript implementation code, Clarity contract requirements, and security notes for SIP-009 non-fungible post-conditions.
    export const generateNonFungiblePostConditionTool: Tool<undefined, typeof NonFungiblePostConditionScheme> = { name: "generate_non_fungible_post_condition", description: "Generate a non-fungible token post-condition for SIP-009 NFTs. Post-conditions are MANDATORY for all NFT transfers.", parameters: NonFungiblePostConditionScheme, execute: async (args, context) => { try { await recordTelemetry({ action: "generate_non_fungible_post_condition" }, context); return `# Non-Fungible Token Post-Condition ## Configuration - **Principal**: ${args.principal} - **Condition**: ${args.conditionCode} - **Token ID**: ${args.tokenId} - **Asset**: ${args.contractAddress}.${args.contractName}.${args.assetName} ## TypeScript Implementation \`\`\`typescript import { makeStandardNonFungiblePostCondition, NonFungibleConditionCode, createAssetInfo, uintCV } from '@stacks/transactions'; const postCondition = makeStandardNonFungiblePostCondition( '${args.principal}', NonFungibleConditionCode.${args.conditionCode === 'owns' ? 'Owns' : 'DoesNotOwn'}, createAssetInfo( '${args.contractAddress}', '${args.contractName}', '${args.assetName}' ), uintCV(${args.tokenId}) ); // Use in transaction const postConditions = [postCondition]; await openContractCall({ // ... other parameters postConditions, postConditionMode: PostConditionMode.Deny, // REQUIRED for security }); \`\`\` ## Clarity Contract Requirements For this post-condition to work, the contract must use native asset functions: \`\`\`clarity ;; REQUIRED: Native non-fungible token definition (define-non-fungible-token ${args.assetName} uint) ;; REQUIRED: Use nft-transfer? for transfers (define-public (transfer (token-id uint) (sender principal) (recipient principal)) (begin ;; ... validation logic ... (try! (nft-transfer? ${args.assetName} token-id sender recipient)) ;; ... rest of function ... ) ) \`\`\` ## Usage Patterns - **${args.conditionCode === 'owns' ? 'Owns' : 'DoesNotOwn'}**: ${args.conditionCode === 'owns' ? `${args.principal} will own NFT #${args.tokenId} after transaction` : `${args.principal} will NOT own NFT #${args.tokenId} after transaction`} ## Security Notes - ✅ This post-condition guarantees ownership state for NFT #${args.tokenId} - ✅ Transaction will fail if ownership doesn't match expectation - ✅ Protects against unauthorized NFT movements - ⚠️ Always verify current ownership before creating conditions`; } catch (error) { return `❌ Failed to generate non-fungible post-condition: ${error}`; } }, };
  • Zod input schema (NonFungiblePostConditionScheme) defining parameters for generating non-fungible post-conditions: principal, conditionCode (owns/does_not_own), tokenId, contractAddress, contractName, assetName.
    const NonFungiblePostConditionScheme = z.object({ principal: z.string().describe("The Stacks address for the post-condition"), conditionCode: NonFungibleConditionCodeScheme.describe("The condition type ('owns' or 'does_not_own')"), tokenId: z.number().describe("The NFT token ID"), contractAddress: z.string().describe("The NFT contract address"), contractName: z.string().describe("The NFT contract name"), assetName: z.string().describe("The NFT asset name (usually same as contract name)"), });
  • Registers the generateNonFungiblePostConditionTool (named 'generate_non_fungible_post_condition') with the FastMCP server instance.
    server.addTool(generateNonFungiblePostConditionTool);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/exponentlabshq/stacks-clarity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server