diff --git a/.changeset/light-bags-raise.md b/.changeset/light-bags-raise.md new file mode 100644 index 00000000..9200bf9a --- /dev/null +++ b/.changeset/light-bags-raise.md @@ -0,0 +1,5 @@ +--- +'@soundxyz/sdk': patch +--- + +Add extra time and hex validations diff --git a/packages/sdk/src/contract/edition-v2/read/create.ts b/packages/sdk/src/contract/edition-v2/read/create.ts index 824113ce..b5cb457e 100644 --- a/packages/sdk/src/contract/edition-v2/read/create.ts +++ b/packages/sdk/src/contract/edition-v2/read/create.ts @@ -10,7 +10,7 @@ import { toHex, } from 'viem' import { MINT_GAS_LIMIT_MULTIPLIER, UINT32_MAX } from '../../../utils/constants' -import { InvalidUint32 } from '../../../utils/errors' +import { InvalidUint32, InvalidTimeValuesError, InvalidBytes32 } from '../../../utils/errors' import { curry, exhaustiveGuard, scaleAmount } from '../../../utils/helpers' import type { Prettify, TransactionGasOptions } from '../../../utils/types' import type { ContractCall } from '../../types' @@ -48,6 +48,11 @@ function isValidUint32(value: number) { return true } +function isValidBytes32(value: Hex) { + // 2 character for '0x' and then 64 characters for 32 bytes (each byte is 2 hex) + return value.length === 66 +} + export function createTieredEditionArgs({ owner, formattedSalt, @@ -85,6 +90,13 @@ export function createTieredEditionArgs({ }) } + if (mintConfig.endTime <= mintConfig.startTime) { + throw new InvalidTimeValuesError({ + startTime: mintConfig.startTime, + endTime: mintConfig.endTime, + }) + } + if (!isValidUint32(mintConfig.maxMintablePerAccount)) { throw new InvalidUint32({ field: 'mintConfig.maxMintablePerAccount', @@ -99,6 +111,20 @@ export function createTieredEditionArgs({ }) } + if (!isValidBytes32(mintConfig.affiliateMerkleRoot)) { + throw new InvalidBytes32({ + field: 'mintConfig.affiliateMerkleRoot', + value: mintConfig.affiliateMerkleRoot, + }) + } + + if (mintConfig.mode === 'VERIFY_MERKLE' && !isValidBytes32(mintConfig.merkleRoot)) { + throw new InvalidBytes32({ + field: 'mintConfig.merkleRoot', + value: mintConfig.merkleRoot, + }) + } + const mode: number = (() => { switch (mintConfig.mode) { case 'DEFAULT': { diff --git a/packages/sdk/src/utils/errors.ts b/packages/sdk/src/utils/errors.ts index 44e70072..bce10c52 100644 --- a/packages/sdk/src/utils/errors.ts +++ b/packages/sdk/src/utils/errors.ts @@ -252,14 +252,12 @@ export class InvalidTimeValuesError extends Error { readonly name = 'InvalidTimeValuesError' readonly startTime: number - readonly cutoffTime: number readonly endTime: number - constructor({ startTime, cutoffTime, endTime }: { startTime: number; cutoffTime: number; endTime: number }) { - super('startTime must be earlier than cutoffTime and cutoffTime must be earlier than endTime') + constructor({ startTime, endTime }: { startTime: number; endTime: number }) { + super('startTime must be earlier than endTime') this.startTime = startTime - this.cutoffTime = cutoffTime this.endTime = endTime } } @@ -299,3 +297,15 @@ export class InvalidUint32 extends Error { this.value = value } } + +export class InvalidBytes32 extends Error { + readonly field: string + readonly value: unknown + + constructor({ field, value }: { field: string; value: unknown }) { + super(`Invalid bytes32 for ${field}, this should be 0x followed by 64 characters, but provided ${String(value)}`) + + this.field = field + this.value = value + } +}