UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

227 lines 9.39 kB
import { z } from 'zod'; import { ZBigNumberish, ZBps, ZChainName, ZHash, } from '../metadata/customZodTypes.js'; import { MAX_BPS_DECIMALS, convertToBps, isBpsPrecisionValid, } from './utils.js'; // Matches the enum in BaseFee.sol export var OnchainTokenFeeType; (function (OnchainTokenFeeType) { OnchainTokenFeeType[OnchainTokenFeeType["LinearFee"] = 1] = "LinearFee"; OnchainTokenFeeType[OnchainTokenFeeType["RegressiveFee"] = 2] = "RegressiveFee"; OnchainTokenFeeType[OnchainTokenFeeType["ProgressiveFee"] = 3] = "ProgressiveFee"; OnchainTokenFeeType[OnchainTokenFeeType["RoutingFee"] = 4] = "RoutingFee"; OnchainTokenFeeType[OnchainTokenFeeType["CrossCollateralRoutingFee"] = 5] = "CrossCollateralRoutingFee"; OnchainTokenFeeType[OnchainTokenFeeType["OffchainQuotedLinearFee"] = 6] = "OffchainQuotedLinearFee"; })(OnchainTokenFeeType || (OnchainTokenFeeType = {})); export var TokenFeeType; (function (TokenFeeType) { TokenFeeType["LinearFee"] = "LinearFee"; TokenFeeType["ProgressiveFee"] = "ProgressiveFee"; TokenFeeType["RegressiveFee"] = "RegressiveFee"; TokenFeeType["RoutingFee"] = "RoutingFee"; TokenFeeType["CrossCollateralRoutingFee"] = "CrossCollateralRoutingFee"; TokenFeeType["OffchainQuotedLinearFee"] = "OffchainQuotedLinearFee"; })(TokenFeeType || (TokenFeeType = {})); export const ImmutableTokenFeeType = [ TokenFeeType.LinearFee, TokenFeeType.RegressiveFee, TokenFeeType.ProgressiveFee, ]; // Mapping between the on-chain token fee type (uint) and the token fee type (string) export const onChainTypeToTokenFeeTypeMap = { [OnchainTokenFeeType.LinearFee]: TokenFeeType.LinearFee, [OnchainTokenFeeType.RegressiveFee]: TokenFeeType.RegressiveFee, [OnchainTokenFeeType.ProgressiveFee]: TokenFeeType.ProgressiveFee, [OnchainTokenFeeType.RoutingFee]: TokenFeeType.RoutingFee, [OnchainTokenFeeType.CrossCollateralRoutingFee]: TokenFeeType.CrossCollateralRoutingFee, [OnchainTokenFeeType.OffchainQuotedLinearFee]: TokenFeeType.OffchainQuotedLinearFee, }; // keccak256("RoutingFee.DEFAULT_ROUTER") export const DEFAULT_ROUTER_KEY = '0x6e086cd647d6eb8b516856666e2c1465fb8a6a58d3a75938362acc674eacaf47'; // ====== SHARED SCHEMAS ====== // For deployed/read configs - token is required for BaseFee implementations export const BaseFeeConfigSchema = z.object({ token: ZHash, owner: ZHash, }); // For input configs - token is NOT specified by user, resolved at deploy time based on token type export const BaseFeeConfigInputSchema = z.object({ owner: ZHash, }); export const FeeParametersSchema = z.object({ maxFee: ZBigNumberish, halfAmount: ZBigNumberish, }); const StandardFeeConfigBaseSchema = BaseFeeConfigSchema.merge(FeeParametersSchema); const BpsConfigSchema = StandardFeeConfigBaseSchema.extend({ bps: ZBps, }); // Shared schema for offchain quote signer configuration export const QuoteSignersSchema = z.object({ quoteSigners: z.array(ZHash).optional(), }); // ====== INDIVIDUAL FEE SCHEMAS ====== export const LinearFeeConfigSchema = BpsConfigSchema.extend({ type: z.literal(TokenFeeType.LinearFee), }); // Linear Fee Input - only requires bps & type, token is optional export const LinearFeeInputConfigSchema = BaseFeeConfigInputSchema.extend({ type: z.literal(TokenFeeType.LinearFee), bps: ZBps.optional(), ...FeeParametersSchema.partial().shape, }) .superRefine((v, ctx) => { const hasBps = v.bps !== undefined; const hasFeeParams = v.maxFee !== undefined && v.halfAmount !== undefined; if (!hasBps && !hasFeeParams) { ctx.addIssue({ code: 'custom', path: ['bps'], message: 'Provide bps or both maxFee and halfAmount', }); } if (hasBps && v.bps <= 0) { ctx.addIssue({ code: 'custom', path: ['bps'], message: 'bps must be > 0', }); } if (hasBps && !isBpsPrecisionValid(v.bps)) { ctx.addIssue({ code: 'custom', path: ['bps'], message: `bps must have at most ${MAX_BPS_DECIMALS} decimal places`, }); } if (v.halfAmount === 0n) { // Prevents divide by 0 ctx.addIssue({ code: 'custom', path: ['halfAmount'], message: 'halfAmount must be > 0', }); } }) .transform((v) => ({ ...v, bps: v.bps ?? convertToBps(v.maxFee, v.halfAmount), })); export const OffchainQuotedLinearFeeConfigSchema = BpsConfigSchema.merge(QuoteSignersSchema).extend({ type: z.literal(TokenFeeType.OffchainQuotedLinearFee), }); export const OffchainQuotedLinearFeeInputConfigSchema = BaseFeeConfigInputSchema.merge(QuoteSignersSchema) .extend({ type: z.literal(TokenFeeType.OffchainQuotedLinearFee), bps: ZBps.optional(), ...FeeParametersSchema.partial().shape, }) .superRefine((v, ctx) => { const hasBps = v.bps !== undefined; const hasFeeParams = v.maxFee !== undefined && v.halfAmount !== undefined; if (!hasBps && !hasFeeParams) { ctx.addIssue({ code: 'custom', path: ['bps'], message: 'Provide bps or both maxFee and halfAmount', }); } if (hasBps && v.bps <= 0) { ctx.addIssue({ code: 'custom', path: ['bps'], message: 'bps must be > 0', }); } if (hasBps && !isBpsPrecisionValid(v.bps)) { ctx.addIssue({ code: 'custom', path: ['bps'], message: `bps must have at most ${MAX_BPS_DECIMALS} decimal places`, }); } if (v.halfAmount === 0n) { ctx.addIssue({ code: 'custom', path: ['halfAmount'], message: 'halfAmount must be > 0', }); } }) .transform((v) => ({ ...v, bps: v.bps ?? convertToBps(v.maxFee, v.halfAmount), })); export const ProgressiveFeeConfigSchema = StandardFeeConfigBaseSchema.extend({ type: z.literal(TokenFeeType.ProgressiveFee), }); export const ProgressiveFeeInputConfigSchema = BaseFeeConfigInputSchema.extend({ type: z.literal(TokenFeeType.ProgressiveFee), maxFee: ZBigNumberish, halfAmount: ZBigNumberish, }).refine((v) => BigInt(v.halfAmount) > 0n, { path: ['halfAmount'], message: 'halfAmount must be > 0', }); export const RegressiveFeeConfigSchema = StandardFeeConfigBaseSchema.extend({ type: z.literal(TokenFeeType.RegressiveFee), }); export const RegressiveFeeInputConfigSchema = BaseFeeConfigInputSchema.extend({ type: z.literal(TokenFeeType.RegressiveFee), maxFee: ZBigNumberish, halfAmount: ZBigNumberish, }).refine((v) => BigInt(v.halfAmount) > 0n, { path: ['halfAmount'], message: 'halfAmount must be > 0', }); export const RoutingFeeConfigSchema = BaseFeeConfigSchema.extend({ type: z.literal(TokenFeeType.RoutingFee), feeContracts: z.record(ZChainName, z.lazy(() => TokenFeeConfigSchema)), // Destination -> Fee }); const CROSS_COLLATERAL_DESTINATION_MESSAGE = 'CrossCollateralRoutingFee destinations must define at least one router fee'; const CrossCollateralRoutingFeeDestinationConfigSchema = z .record(ZHash, z.lazy(() => TokenFeeConfigSchema)) .refine((value) => Object.keys(value).length > 0, { message: CROSS_COLLATERAL_DESTINATION_MESSAGE, }); export const CrossCollateralRoutingFeeConfigSchema = z.object({ type: z.literal(TokenFeeType.CrossCollateralRoutingFee), owner: ZHash, feeContracts: z.record(ZChainName, CrossCollateralRoutingFeeDestinationConfigSchema), // Destination -> { routerKey -> Fee }, including DEFAULT_ROUTER_KEY }); // Routing Fee Input - maxFee/halfAmount NOT configurable (contract hardcodes to max uint256) export const RoutingFeeInputConfigSchema = BaseFeeConfigInputSchema.extend({ type: z.literal(TokenFeeType.RoutingFee), feeContracts: z.record(ZChainName, z.lazy(() => TokenFeeConfigInputSchema)), }).refine((value) => Object.keys(value.feeContracts).length > 0, { path: ['feeContracts'], message: 'RoutingFee must define at least one destination fee', }); const CrossCollateralRoutingFeeDestinationInputConfigSchema = z .record(ZHash, z.lazy(() => TokenFeeConfigInputSchema)) .refine((value) => Object.keys(value).length > 0, { message: CROSS_COLLATERAL_DESTINATION_MESSAGE, }); export const CrossCollateralRoutingFeeInputConfigSchema = BaseFeeConfigInputSchema.extend({ type: z.literal(TokenFeeType.CrossCollateralRoutingFee), feeContracts: z.record(ZChainName, CrossCollateralRoutingFeeDestinationInputConfigSchema), }).refine((value) => Object.keys(value.feeContracts).length > 0, { path: ['feeContracts'], message: 'CrossCollateralRoutingFee must define at least one destination fee', }); // ====== UNION SCHEMAS ====== export const TokenFeeConfigSchema = z.discriminatedUnion('type', [ LinearFeeConfigSchema, OffchainQuotedLinearFeeConfigSchema, ProgressiveFeeConfigSchema, RegressiveFeeConfigSchema, RoutingFeeConfigSchema, CrossCollateralRoutingFeeConfigSchema, ]); export const TokenFeeConfigInputSchema = z.union([ LinearFeeInputConfigSchema, OffchainQuotedLinearFeeInputConfigSchema, ProgressiveFeeInputConfigSchema, RegressiveFeeInputConfigSchema, RoutingFeeInputConfigSchema, CrossCollateralRoutingFeeInputConfigSchema, ]); //# sourceMappingURL=types.js.map