@malda-protocol/protocol-config
TypeScript icon, indicating that this package has built-in type declarations

1.0.4 • Public • Published

@malda-protocol/protocol-config

npm version TypeScript

Centralized contract addresses, constants, and token configurations for Malda Protocol across different environments and blockchain networks.

Features

  • 🔒 Type-safe: Full TypeScript support with strict typing
  • 🌐 Multi-chain: Support for Mainnet, Arbitrum, Optimism, Base, and Linea
  • 🏗️ Multi-environment: Separate production and testnet configurations
  • Runtime validation: Zod schemas for configuration validation
  • 🔒 Type-safe ABIs: Full TypeScript inference for viem/wagmi contract interactions
  • 🎯 Tree-shakeable: Import only what you need
  • 📦 Zero dependencies: Minimal runtime dependencies (viem + zod)

Installation

npm install @malda-protocol/protocol-config
# or
yarn add @malda-protocol/protocol-config
# or
pnpm add @malda-protocol/protocol-config

Quick Start

import { PRODUCTION_CONFIG, PRODUCTION_TOKENS } from '@malda-protocol/protocol-config/production'

// Get the production configuration
console.log(PRODUCTION_CONFIG.hostChainId) // 59144 (Linea)
console.log(PRODUCTION_CONFIG.operator) // "0x05bD298c0C3F34B541B42F867BAF6707911BE437"

// Get production tokens
console.log(PRODUCTION_TOKENS) // Array of all production tokens

Usage Examples

Environment-Specific Imports

// Production configuration
import * as production from '@malda-protocol/protocol-config/production'
console.log(production.PRODUCTION_CONFIG)
console.log(production.PRODUCTION_TOKENS)

// Testnet configuration
import * as testnet from '@malda-protocol/protocol-config/testnet'
console.log(testnet.TESTNET_CONFIG)
console.log(testnet.TESTNET_TOKENS)

Individual Token Access

import { production, testnet } from '@malda-protocol/protocol-config'

// Production tokens
const prodUSDC = production.USDC
const prodWETH = production.WETH

// Testnet tokens
const testUSDC = testnet.USDC
const testWETH = testnet.WETH

Chain-Specific Operations

import { getMarketsForChain, isMarketSupportedOnChain, TOKENS } from '@malda-protocol/protocol-config'
import { mainnet, base, linea } from '@wagmi/core/chains'

// Get markets available on Base
const baseMarkets = getMarketsForChain(TOKENS, base.id)

// Check if USDC is supported on Linea
const usdcToken = TOKENS.find((t) => t.symbol === 'USDC')
const isSupported = isMarketSupportedOnChain(usdcToken!, linea.id)

Using with Wagmi Chains

import { mainnet, arbitrum, optimism, base, linea } from '@wagmi/core/chains'
import {
  getMarketsForChainObject,
  isMarketSupportedOnChainObject,
  getSupportedChainsForMarket,
  getNativeCurrencySymbol,
  getProductionChains,
} from '@malda-protocol/protocol-config'
import { PRODUCTION_CONFIG, PRODUCTION_TOKENS } from '@malda-protocol/protocol-config/production'

// Get markets available on Base chain
const baseMarkets = getMarketsForChainObject(PRODUCTION_TOKENS, base)
console.log(`${baseMarkets.length} markets available on ${base.name}`)

// Check if a specific token is supported on a wagmi chain
const usdcToken = PRODUCTION_TOKENS.find((t) => t.symbol === 'USDC')
const isUsdcOnArbitrum = isMarketSupportedOnChainObject(usdcToken!, arbitrum)

// Get all chains that support a specific token
const supportedChains = getSupportedChainsForMarket(
  usdcToken,
  [mainnet, arbitrum, optimism, base, linea],
  PRODUCTION_CONFIG
)

// Access wagmi chain properties
supportedChains.forEach((chain) => {
  console.log(`${chain.name}: ${getNativeCurrencySymbol(chain)}`)
  console.log(`Block Explorer: ${chain.blockExplorers?.default?.url}`)
  console.log(`RPC: ${chain.rpcUrls.default?.http[0]}`)
})

// Filter production chains only
const allChains = [mainnet, arbitrum, optimism, base, linea]
const productionChains = getProductionChains(allChains)

Using ABIs with Viem/Wagmi

import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { useReadContract } from 'wagmi'
import {
  ERC20_ABI,
  OPERATOR_ABI,
  MTOKEN_ABI,
} from '@malda-protocol/protocol-config/abis'
import { PRODUCTION_CONFIG } from '@malda-protocol/protocol-config/production'

// With viem - full type safety!
const client = createPublicClient({
  chain: mainnet,
  transport: http(),
})

const balance = await client.readContract({
  address: '0x...', // USDC address
  abi: ERC20_ABI,
  functionName: 'balanceOf', // ✅ Autocompleted and type-safe
  args: ['0x...'], // ✅ Args are type-checked
})

// With wagmi hooks - also type-safe!
function MyComponent() {
  const { data: liquidity } = useReadContract({
    address: PRODUCTION_CONFIG.operator,
    abi: OPERATOR_ABI,
    functionName: 'getAccountLiquidity', // ✅ Type-safe
    args: ['0x...'], // ✅ Type-checked
  })

  return <div>Liquidity: {liquidity?.toString()}</div>
}

// Dynamic ABI loading (for code splitting)
import { getABI } from '@malda-protocol/protocol-config/abis'

const erc20Abi = await getABI('ERC20')

Runtime Validation

import { schemas, ProtocolConfigSchema } from '@malda-protocol/protocol-config'

// Validate a configuration object
const config = {
  /* ... */
}
const result = ProtocolConfigSchema.safeParse(config)

if (result.success) {
  console.log('Configuration is valid!')
} else {
  console.error('Validation errors:', result.error.issues)
}

API Reference

Core Types

interface ProtocolConfig {
  hostChainId: number
  operator: Address
  priceOracle: Address
  blocksPerYear: number
  batchSubmitter: Address
  paymentReceiver: Address
  // ... more fields
  assets: ProtocolAsset[]
  supportedChainIds: number[]
}

interface Token {
  name: string
  symbol: AssetSymbol
  decimals: number
  address: Address // mToken address
  underlyingAddresses: { [chainId: number]: Address }
  supportedChainIds?: number[]
}

Constants

  • PRODUCTION_CHAINS, TESTNET_CHAINS, ALL_CHAINS: Wagmi chain objects for supported chains
  • ASSET_SYMBOLS: All supported asset symbols

Environment-Specific Constants

Use explicit imports for configuration and tokens:

// Production
import { PRODUCTION_CONFIG, PRODUCTION_TOKENS } from '@malda-protocol/protocol-config/production'

// Testnet
import { TESTNET_CONFIG, TESTNET_TOKENS } from '@malda-protocol/protocol-config/testnet'

ABIs

All ABIs are shared across environments and provide full TypeScript support:

  • ERC20_ABI: Standard ERC20 token interface
  • OPERATOR_ABI: Malda protocol operator contract
  • MTOKEN_ABI: Malda mToken contract
  • MTOKEN_GATEWAY_ABI: Malda mToken gateway contract
  • DELEGATOR_ABI: Malda delegator contract
  • BATCH_SUBMITTER_ABI: Malda batch submitter contract
  • MIGRATOR_ABI: Malda migrator contract
  • PAYMENT_RECEIVER_ABI: Malda payment receiver contract
  • PRICE_ORACLE_ABI: Malda price oracle contract
  • REFERRAL_SIGNING_ABI: Malda referral signing contract
  • USDT_MAINNET_ABI: USDT mainnet specific ABI
  • getABI(name): Dynamic ABI loader for code splitting
  • ABIS: Collection of all available ABIs with lazy loading

Utility Functions

Chain Operations (Primary API - supports wagmi Chain objects)

  • isMarketSupportedOnChainObject(token, chain): Check if a token is supported on a wagmi chain
  • getMarketsForChainObject(tokens, chain): Get all tokens available on a wagmi chain
  • getSupportedChainsForMarket(token, allChains, config): Get supported wagmi chains for a token
  • getUnderlyingAddressForChain(token, chain): Get underlying token address for a wagmi chain
  • findChainById(chainId, chains): Find a wagmi chain object by its ID
  • createTokensFromConfig(config): Transform protocol assets into simplified token format

Wagmi Chain Utilities

  • getNativeCurrencySymbol(chain): Get the native currency symbol (e.g., 'ETH')
  • getRpcUrl(chain): Get the first RPC URL for a chain
  • getBlockExplorerUrl(chain): Get the block explorer URL for a chain
  • isTestnetChain(chain): Check if a wagmi chain is a testnet
  • getProductionChains(): Get predefined production (mainnet) chains
  • getTestnetChains(): Get predefined testnet chains

Legacy Chain ID Operations

  • isMarketSupportedOnChain(token, chainId): Check if a token is supported on a chain ID
  • getMarketsForChain(tokens, chainId): Get all tokens available on a chain ID
  • getUnderlyingAddress(token, chainId): Get underlying token address by chain ID

Supported Assets

Symbol Name Decimals Networks
USDC USD Coin 6 All
WETH Wrapped Ether 18 All
USDT USD Tether 6 All
WBTC Wrapped BTC 8 All
wstETH Wrapped liquid staked ETH 18 All
ezETH Renzo Restaked ETH 18 Linea only
weETH Wrapped eETH 18 All
wrsETH Wrapped rsETH 18 All

Supported Networks

Production

  • Ethereum Mainnet (1)
  • Arbitrum One (42161)
  • Optimism (10)
  • Base (8453)
  • Linea (59144) - Host Chain

Testnet

  • Sepolia (11155111)
  • Linea Sepolia (59141) - Host Chain
  • Optimism Sepolia (11155420)

Development

# Install dependencies
pnpm install

# Build the package
pnpm run build

# Type check
pnpm run type-check

# Development mode (watch)
pnpm run dev

# Publishing check
pnpm run publish:check

Contributing

  1. All address and constant changes must be submitted via Pull Request
  2. Changes require mandatory review (see CODEOWNERS)
  3. Update version using npm version patch|minor|major
  4. Follow semantic versioning

Version Control

This package uses semantic versioning. When making changes:

  • Patch (1.0.x): Bug fixes, address updates
  • Minor (1.x.0): New features, new assets, new chains
  • Major (x.0.0): Breaking changes to the API

Releasing

# Release a patch version
pnpm run release:patch

# Release a minor version
pnpm run release:minor

# Release a major version
pnpm run release:major

License

MIT © Malda Protocol

Package Sidebar

Install

npm i @malda-protocol/protocol-config

Weekly Downloads

33

Version

1.0.4

License

MIT

Unpacked Size

896 kB

Total Files

68

Last publish

Collaborators

  • nimrodel_eth