Create a validation strategy

Create a validation strategy and use it in your own space

To add your own voting validation strategy on Snapshot you need to fork the snapshot-strategies repository and create a pull request.

https://github.com/snapshot-labs/snapshot-strategies

1. Navigate to the src\validations.

└── src
    └── validations
        └── basic

2. Create a copy of the basic strategy folder and rename it to the name of your voting validation.

3. Customize the logic of your voting validation.

If you are not sure about the Validation class, have a look at its definition:

https://github.com/snapshot-labs/snapshot-strategies/blob/master/src/validations/validation.ts
import snapshot from '@snapshot-labs/snapshot.js';
import { DEFAULT_SUPPORTED_PROTOCOLS } from '../constants';
import { Protocol, Snapshot } from '../types';

export default class Validation {
  public id = '';
  public github = '';
  public version = '';
  public title = '';
  public description = '';
  public supportedProtocols: Protocol[] = DEFAULT_SUPPORTED_PROTOCOLS;
  public hasInnerStrategies = false;

  public author: string;
  public space: string;
  public network: string;
  public snapshot: Snapshot;
  public params: any;

  constructor(
    author: string,
    space: string,
    network: string,
    snapshot: Snapshot,
    params: any
  ) {
    this.author = author;
    this.space = space;
    this.network = network;
    this.snapshot = snapshot;
    this.params = params;
  }

  async validate(customAuthor = this.author): Promise<boolean> {
    try {
      this.validateAddressType(customAuthor);
    } catch (e) {
      return false;
    }

    return this.doValidate(customAuthor);
  }

  // Abstract method to be implemented by subclasses
  // This contains the actual validation logic without global/commons validation
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  protected async doValidate(_customAuthor: string): Promise<boolean> {
    return true;
  }

  private validateAddressType(address: string): boolean {
    try {
      const formattedAddress = snapshot.utils.getFormattedAddress(address);

      if (
        (snapshot.utils.isEvmAddress(formattedAddress) &&
          this.supportedProtocols.includes('evm')) ||
        (snapshot.utils.isStarknetAddress(formattedAddress) &&
          this.supportedProtocols.includes('starknet'))
      ) {
        return true;
      }
    } catch (error) {
      // If isStarknetAddress throws an error, fall through to the standard error
    }

    throw new Error(
      `Address "${address}" is not a valid ${this.supportedProtocols.join(
        ' or '
      )} address`
    );
  }
}

The validation name has to be included in the index.ts in the validationClasses variable.

4. Test your validation

To make sure your validation passes all tests, run:

npm run test --validation=<VALIDATION NAME> // replace <VALIDATION NAME>

4. Make sure you pass the checklist

Have a look here on the requirements for adding a new validation strategy and make sure you fulfill the points in the checklist:

https://github.com/snapshot-labs/snapshot-strategies#checklist-for-adding-a-new-strategy

5. Create a pull request

The team will then review your PR and after it's approved and merged it will be available to choose in your space settings.

Last updated

Was this helpful?