Skip to content

Commit

Permalink
fix: change SignatureLikeSchema to HexBytesSchema
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Mar 10, 2025
1 parent ece3bfa commit d2a7a3b
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function messageConfirmationBuilder(): IBuilder<MessageConfirmation> {
.with('owner', getAddress(faker.finance.ethereumAddress()))
.with(
'signature',
faker.string.hexadecimal({ length: 32 }) as `0x${string}`,
faker.string.hexadecimal({ length: 130 }) as `0x${string}`,
)
.with('signatureType', faker.helpers.objectValue(SignatureType));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('MessageConfirmationSchema', () => {
},
{
code: 'custom',
message: 'Invalid signature',
message: 'Invalid hex bytes',
path: ['signature'],
},
]),
Expand Down
5 changes: 3 additions & 2 deletions src/domain/messages/entities/message-confirmation.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SignatureType } from '@/domain/common/entities/signature-type.entity';
import { AddressSchema } from '@/validation/entities/schemas/address.schema';
import { SignatureLikeSchema } from '@/validation/entities/schemas/signature.schema';
import { HexBytesSchema } from '@/validation/entities/schemas/hexbytes.schema';
import { z } from 'zod';

export type MessageConfirmation = z.infer<typeof MessageConfirmationSchema>;
Expand All @@ -9,6 +9,7 @@ export const MessageConfirmationSchema = z.object({
created: z.coerce.date(),
modified: z.coerce.date(),
owner: AddressSchema,
signature: SignatureLikeSchema,
// We don't validate signature length as they are on the Transaction Service
signature: HexBytesSchema,
signatureType: z.nativeEnum(SignatureType),
});
5 changes: 3 additions & 2 deletions src/domain/safe/entities/multisig-transaction.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { HexSchema } from '@/validation/entities/schemas/hex.schema';
import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema';
import { z } from 'zod';
import { CoercedNumberSchema } from '@/validation/entities/schemas/coerced-number.schema';
import { SignatureLikeSchema } from '@/validation/entities/schemas/signature.schema';
import { HexBytesSchema } from '@/validation/entities/schemas/hexbytes.schema';

export type Confirmation = z.infer<typeof ConfirmationSchema>;

Expand All @@ -18,7 +18,8 @@ export const ConfirmationSchema = z.object({
submissionDate: z.coerce.date(),
transactionHash: HexSchema.nullish().default(null),
signatureType: z.nativeEnum(SignatureType),
signature: SignatureLikeSchema.nullish().default(null),
// We don't validate signature length as they are on the Transaction Service
signature: HexBytesSchema.nullish().default(null),
});

export const MultisigTransactionSchema = z.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ describe('CreateMessageDtoSchema', () => {
message: 'Invalid "0x" notated hex string',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid hex bytes',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid signature',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ describe('UpdateMessageSignatureDtoSchema', () => {
message: 'Invalid "0x" notated hex string',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid hex bytes',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid signature',
Expand All @@ -54,6 +59,11 @@ describe('UpdateMessageSignatureDtoSchema', () => {

expect(!result.success && result.error).toStrictEqual(
new ZodError([
{
code: 'custom',
message: 'Invalid hex bytes',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid signature',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ describe('ProposeTransactionDtoSchema', () => {
message: 'Invalid "0x" notated hex string',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid hex bytes',
path: ['signature'],
},
{
code: 'custom',
message: 'Invalid signature',
Expand Down
26 changes: 26 additions & 0 deletions src/validation/entities/schemas/__tests__/hexbytes.schema.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { faker } from '@faker-js/faker';
import { HexBytesSchema } from '@/validation/entities/schemas/hexbytes.schema';

describe('HexBytesSchema', () => {
it('should return true if the value is a valid hex bytes', () => {
const value = faker.string.hexadecimal({ length: 4 });

const result = HexBytesSchema.safeParse(value);

expect(result.success).toBe(true);
});

it('should return false if the value is not a valid hex bytes', () => {
const value = faker.string.hexadecimal({ length: 3 });

const result = HexBytesSchema.safeParse(value);

expect(!result.success && result.error.issues).toStrictEqual([
{
code: 'custom',
message: 'Invalid hex bytes',
path: [],
},
]);
});
});
53 changes: 6 additions & 47 deletions src/validation/entities/schemas/__tests__/signature.schema.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { faker } from '@faker-js/faker';
import {
SignatureLikeSchema,
SignatureSchema,
} from '@/validation/entities/schemas/signature.schema';
import { SignatureSchema } from '@/validation/entities/schemas/signature.schema';

describe('SignatureSchema', () => {
it('should validate a signature', () => {
Expand Down Expand Up @@ -38,68 +35,30 @@ describe('SignatureSchema', () => {
},
{
code: 'custom',
message: 'Invalid signature',
message: 'Invalid hex bytes',
path: [],
},
]);
});

it('should not validate a incorrect length signature', () => {
const signature = faker.string.hexadecimal({
length: 129,
}) as `0x${string}`;

const result = SignatureSchema.safeParse(signature);

expect(!result.success && result.error.issues).toStrictEqual([
{
code: 'custom',
message: 'Invalid signature',
path: [],
},
]);
});
});

describe('SignatureLikeSchema', () => {
it('should validate a signature', () => {
it('should not validate a incorrect length signature', () => {
const signature = faker.string.hexadecimal({
// Somewhat "standard" length for dynamic signature
length: 130 + 64,
length: 129,
}) as `0x${string}`;

const result = SignatureLikeSchema.safeParse(signature);

expect(result.success).toBe(true);
});

it('should not validate a non-hex signature', () => {
const signature = faker.string.alphanumeric() as `0x${string}`;

const result = SignatureLikeSchema.safeParse(signature);
const result = SignatureSchema.safeParse(signature);

expect(!result.success && result.error.issues).toStrictEqual([
{
code: 'custom',
message: 'Invalid "0x" notated hex string',
path: [],
},
{
code: 'custom',
message: 'Invalid signature',
message: 'Invalid hex bytes',
path: [],
},
]);
});

it('should not validate a incorrect length signature', () => {
const signature = faker.string.hexadecimal({
length: 129,
}) as `0x${string}`;

const result = SignatureLikeSchema.safeParse(signature);

expect(!result.success && result.error.issues).toStrictEqual([
{
code: 'custom',
message: 'Invalid signature',
Expand Down
9 changes: 9 additions & 0 deletions src/validation/entities/schemas/hexbytes.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { HexSchema } from '@/validation/entities/schemas/hex.schema';

function isHexBytes(value: `0x${string}`): boolean {
return value.length % 2 === 0;
}

export const HexBytesSchema = HexSchema.refine(isHexBytes, {
message: 'Invalid hex bytes',
});
15 changes: 2 additions & 13 deletions src/validation/entities/schemas/signature.schema.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HexSchema } from '@/validation/entities/schemas/hex.schema';
import { HexBytesSchema } from '@/validation/entities/schemas/hexbytes.schema';

// This does not take dynamic parts into account but we can safely
// apply it to proposed signatures as we do not support contract
Expand All @@ -8,17 +8,6 @@ function isSignature(value: `0x${string}`): boolean {
return (value.length - 2) % 130 === 0;
}

export const SignatureSchema = HexSchema.refine(isSignature, {
message: 'Invalid signature',
});

// As indexed signatures may be contract signatures, we need to assume
// that signatures from our API may have a dynamic part meaning that
// we can only check that the length is "byte-aligned"
function isSignatureLike(value: `0x${string}`): boolean {
return value.length % 2 === 0;
}

export const SignatureLikeSchema = HexSchema.refine(isSignatureLike, {
export const SignatureSchema = HexBytesSchema.refine(isSignature, {
message: 'Invalid signature',
});

0 comments on commit d2a7a3b

Please sign in to comment.