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