Skip to content

Add Stellar address validation middleware for authorAddress field #605

@BigBen-7

Description

@BigBen-7

Description

The authorAddress field in CreateGistDto currently accepts any string. Since GistPin is built on Stellar, author addresses must be valid Stellar public keys — Ed25519, StrKey-encoded, starting with G, 56 characters long. This issue adds proper Stellar address validation.

Context

  • Stellar public keys are Base32-encoded and always start with G
  • Example: GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN
  • The Stellar SDK provides StrKey.isValidEd25519PublicKey() for validation
  • The authorAddress field is optional — anonymous posts are allowed

Requirements

  • Install @stellar/stellar-sdk if not already present
  • Create a custom class-validator decorator @IsStellarAddress()
  • The decorator should call StrKey.isValidEd25519PublicKey() from the Stellar SDK
  • Apply the decorator to authorAddress in CreateGistDto
  • Keep authorAddress optional — only validate format when it IS provided
  • Return a clear 400 error: authorAddress must be a valid Stellar public key
  • Add the same validation to any future DTOs that accept Stellar addresses

Files to Touch

  • Backend/src/common/validators/stellar-address.validator.ts — create custom decorator
  • Backend/src/gists/dto/create-gist.dto.ts — apply @IsStellarAddress() to authorAddress
  • Backend/src/common/validators/index.ts — export the validator

Custom Validator Structure

import { registerDecorator, ValidationOptions } from 'class-validator';
import { StrKey } from '@stellar/stellar-sdk';

export function IsStellarAddress(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isStellarAddress',
      target: object.constructor,
      propertyName,
      options: validationOptions,
      validator: {
        validate(value: unknown) {
          return typeof value === 'string' && StrKey.isValidEd25519PublicKey(value);
        },
        defaultMessage() {
          return 'authorAddress must be a valid Stellar public key';
        },
      },
    });
  };
}

Acceptance Criteria

  • POST /gists with invalid authorAddress returns 400 with clear message
  • POST /gists with valid Stellar address starting with G succeeds
  • POST /gists with no authorAddress succeeds as anonymous post
  • Unit tests cover valid, invalid, and missing address cases

Complexity: 200 points

Metadata

Metadata

Assignees

No one assigned

    Labels

    BackendBackend issues

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions