Skip to main content

Documentation Index

Fetch the complete documentation index at: https://litprotocol-vincent.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The evaluate function provides final validation with full blockchain access in the Lit Action environment. This is where your Policy makes the definitive allow/deny decision.

Function Parameters

The evaluate function receives two parameters:
params
object
required
Object containing the ability and user parameters
policyContext
object
required
Context object provided by the SDK with helpers and metadata

Response Schemas

Allow Response

evalAllowResultSchema
ZodSchema
required
A Zod schema that defines the structure of successful evaluation results. Include details about why the evaluation passed, such as current state and validation context.

Deny Response

evalDenyResultSchema
ZodSchema
required
A Zod schema that defines the structure of failed evaluation results. Include details about why the evaluation failed, such as exceeded limits or validation errors.
import { createVincentPolicy } from '@lit-protocol/vincent-ability-sdk';
import { z } from 'zod';

const vincentPolicy = createVincentPolicy({
  // ... other policy definitions

  evalAllowResultSchema: z.object({
    maxDailySpendingLimit: z.number(),
    currentDailySpending: z.number(),
    allowedTokens: z.array(z.string()),
  }),
});
If any unhandled error occurs during evaluation, the Vincent Ability SDK automatically returns a deny result with the error message.

Example Implementation

import { createVincentPolicy } from '@lit-protocol/vincent-ability-sdk';
import { z } from 'zod';

const vincentPolicy = createVincentPolicy({
  // ... other policy definitions

  evalAllowResultSchema: z.object({
    maxDailySpendingLimit: z.number(),
    currentDailySpending: z.number(),
    allowedTokens: z.array(z.string()),
  }),

  evalDenyResultSchema: z.object({
    reason: z.string(),
    maxDailySpendingLimit: z.number(),
    currentDailySpending: z.number(),
    allowedTokens: z.array(z.string()),
  }),

  evaluate: async ({ abilityParams, userParams }, policyContext) => {
    const { amount, tokenAddress } = abilityParams;
    const { dailySpendingLimit, allowedTokens } = userParams;

    const isTokenAllowed = allowedTokens.includes(tokenAddress);
    const { isSpendingLimitExceeded, currentDailySpending } = await checkSpendingLimit(
      tokenAddress,
      amount,
      dailySpendingLimit,
    );

    if (!isTokenAllowed) {
      return policyContext.deny({
        reason: 'Token not allowed',
        maxDailySpendingLimit: dailySpendingLimit,
        currentDailySpending,
        allowedTokens: allowedTokens,
      });
    }

    if (isSpendingLimitExceeded) {
      return policyContext.deny({
        reason: 'Spending limit exceeded',
        maxDailySpendingLimit: dailySpendingLimit,
        currentDailySpending,
        allowedTokens: allowedTokens,
      });
    }

    return policyContext.allow({
      maxDailySpendingLimit: dailySpendingLimit,
      currentDailySpending,
      allowedTokens: allowedTokens,
    });
  },
});

Best Practices

  1. Use Fresh Data - Query current state rather than relying on cached values
  2. Consistent with Precheck - Apply the same validation logic as your precheck function
  3. Handle Errors Gracefully - Provide clear error messages for debugging
  4. Return Context - Include current state information in allow/deny responses

Next Steps

Commit Function

Update policy state after successful execution

Publishing Policies

Publish your policy for use in Vincent Apps