From 47afc402fa70b628cd29fb22e0f1b0bb548852d8 Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Thu, 26 Sep 2024 14:18:57 +0200 Subject: [PATCH] swap `zod` with `superstruct` --- packages/sdk/package.json | 4 +- packages/sdk/src/validators.ts | 102 ++++++++++++++++++++++++--------- packages/sdk/tsconfig.json | 2 +- yarn.lock | 11 +++- 4 files changed, 86 insertions(+), 33 deletions(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index cfef315..fb6b644 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -17,8 +17,8 @@ "typescript": "^5.0.3" }, "dependencies": { - "viem": "^2.21.9", - "zod": "^3.23.8" + "superstruct": "^2.0.2", + "viem": "^2.21.9" }, "volta": { "node": "20.17.0", diff --git a/packages/sdk/src/validators.ts b/packages/sdk/src/validators.ts index 834b4bf..542913d 100644 --- a/packages/sdk/src/validators.ts +++ b/packages/sdk/src/validators.ts @@ -1,42 +1,88 @@ -import { array, number, object, string, union } from "zod"; +import { + array, + assign, + bigint, + define, + number, + object, + optional, + refine, + string, + type Struct, + union, +} from "superstruct"; + +const hexString = (): Struct => + define("hexString", (value) => { + if (typeof value !== "string") return false; + const hexRegex = /^0x[0-9a-fA-F]+$/; + return hexRegex.test(value); + }); + +const numberLike = refine( + union([number(), hexString(), bigint()]), + "numberLike", + (value) => { + if (typeof value === "string") return !isNaN(Number(value)); + return true; // If it's a number or bigint, it's already valid + }, +); const BridgeCoreSchema = object({ - account: string(), + account: hexString(), destinationChain: number(), token: string(), - amount: number(), - threshold: number().optional(), + amount: numberLike, + threshold: optional(number()), }); const ContractCallCoreSchema = object({ - callData: string(), - contractAddress: string(), - gasLimit: number(), + callData: hexString(), + contractAddress: hexString(), + gasLimit: numberLike, }); -const NativeContractCallSchema = ContractCallCoreSchema.extend({ - recipient: string(), -}); +const NativeContractCallSchema = assign( + ContractCallCoreSchema, + object({ + recipient: hexString(), + }), +); -const TokenContractCallSchema = ContractCallCoreSchema.extend({ - outputTokenAddress: string().optional(), - approvalAddress: string().optional(), -}); +const TokenContractCallSchema = assign( + ContractCallCoreSchema, + object({ + outputTokenAddress: optional(hexString()), + approvalAddress: optional(hexString()), + }), +); -export const SingleHopSchema = BridgeCoreSchema.extend({ - sourceChains: number(), // whitelistedSourceChains -}); +export const SingleHopSchema = assign( + BridgeCoreSchema, + object({ + sourceChains: number(), // whitelistedSourceChains + }), +); -export const MultiHopSchema = BridgeCoreSchema.extend({ - sourceChains: array(number()), // whitelistedSourceChains -}); +export const MultiHopSchema = assign( + BridgeCoreSchema, + object({ + sourceChains: array(number()), // whitelistedSourceChains + }), +); -export const SingleHopWithContractSchema = BridgeCoreSchema.extend({ - contractCall: union([NativeContractCallSchema, TokenContractCallSchema]), - sourceChains: number(), // whitelistedSourceChains -}); +export const SingleHopWithContractSchema = assign( + BridgeCoreSchema, + object({ + contractCall: union([NativeContractCallSchema, TokenContractCallSchema]), + sourceChains: number(), // whitelistedSourceChains + }), +); -export const MultiHopWithContractSchema = BridgeCoreSchema.extend({ - contractCall: union([NativeContractCallSchema, TokenContractCallSchema]), - sourceChains: array(number()), // whitelistedSourceChains -}); +export const MultiHopWithContractSchema = assign( + BridgeCoreSchema, + object({ + contractCall: union([NativeContractCallSchema, TokenContractCallSchema]), + sourceChains: array(number()), // whitelistedSourceChains + }), +); diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json index 0564f0c..b27439e 100644 --- a/packages/sdk/tsconfig.json +++ b/packages/sdk/tsconfig.json @@ -78,7 +78,7 @@ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ diff --git a/yarn.lock b/yarn.lock index 4c49a09..440cabd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1868,9 +1868,9 @@ __metadata: "@types/eslint": "npm:^8.56.11" "@types/node": "npm:18.19.42" eslint: "npm:^8.57.0" + superstruct: "npm:^2.0.2" typescript: "npm:^5.0.3" viem: "npm:^2.21.9" - zod: "npm:^3.23.8" languageName: unknown linkType: soft @@ -17940,6 +17940,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^2.0.2": + version: 2.0.2 + resolution: "superstruct@npm:2.0.2" + checksum: 10c0/c6853db5240b4920f47b3c864dd1e23ede6819ea399ad29a65387d746374f6958c5f1c5b7e5bb152d9db117a74973e5005056d9bb83c24e26f18ec6bfae4a718 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -20120,7 +20127,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.21.4, zod@npm:^3.22.3, zod@npm:^3.23.8": +"zod@npm:^3.21.4, zod@npm:^3.22.3": version: 3.23.8 resolution: "zod@npm:3.23.8" checksum: 10c0/8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69