npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fevertokens/sdk

v0.0.5

Published

TypeScript SDK for Fever smart contract deployment and management

Downloads

7

Readme

@fevertokens/sdk

TypeScript SDK for Fever smart contract deployment and management

npm version License: Proprietary Node Version

Bring manifest-driven smart contract deployment to your TypeScript/Node.js projects. Deploy contracts, POF packages, and complex multi-package systems with a clean, type-safe API.


Table of Contents


Why @fevertokens/sdk?

The Problem

Traditional smart contract deployment is painful:

  • ❌ Write custom deployment scripts for every contract
  • ❌ Manually manage contract addresses and dependencies
  • ❌ No consistent approach across projects
  • ❌ Hard to track what's deployed where
  • ❌ Hit 24KB contract size limits

The Solution

Manifest-driven deployment + Package-Oriented Framework (POF)

import { FeverDeployer } from '@fevertokens/sdk'

const deployer = new FeverDeployer({
  wallet: { type: 'privateKey', value: process.env.PRIVATE_KEY! },
  network: { chainId: 1337, rpcUrl: 'http://localhost:8545' }
})

// Deploy a complete lending system with one call
const result = await deployer.deploy({
  kind: 'PackageSystem',
  spec: {
    system: { name: 'LendingApplication' },
    packages: [
      { name: 'LoanRegistry' },
      { name: 'LoanFunding' },
      { name: 'LoanRepayment' },
      { name: 'LoanTokenManager' }
    ]
  }
})

console.log(`✓ System deployed to ${result.address}`)
console.log(`✓ Packages attached: ${result.packages.length}`)

One call deploys everything, manages dependencies, and tracks results.


Installation

npm

npm install @fevertokens/sdk ethers

yarn

yarn add @fevertokens/sdk ethers

pnpm

pnpm add @fevertokens/sdk ethers

Requirements:

  • Node.js >= 18
  • ethers v6.x

Quick Start

Deploy a simple contract in 3 minutes:

import { FeverDeployer } from '@fevertokens/sdk'

// 1. Create deployer
const deployer = new FeverDeployer({
  wallet: { type: 'privateKey', value: '0x...' },
  network: { chainId: 1337, rpcUrl: 'http://localhost:8545' }
})

// 2. Deploy
const result = await deployer.deploy({
  apiVersion: 'beta/v1',
  kind: 'Contract',
  spec: {
    contract: {
      name: 'MyToken',
      constructorArgs: [
        { value: 'My Token' },
        { value: 'MTK' }
      ]
    }
  }
})

console.log(`Deployed to: ${result.address}`)

Core Concepts

1. Manifest-Driven Deployment

Instead of scripts, declare what you want:

// Before: Complex custom script
const token = await TokenFactory.deploy("My Token", "MTK")
const vault = await VaultFactory.deploy(token.address)
// ... manage addresses, gas, errors manually

// After: Simple manifest
kind: Contract
spec:
  contract:
    name: MyToken
    constructorArgs: ["My Token", "MTK"]

2. Three Deployment Types

Contract - Regular smart contracts

kind: 'Contract'
spec: {
  contract: { name: 'MyToken', constructorArgs: [...] }
}

Use for: ERC20, NFTs, utilities, or any regular contract

Package - POF packages

kind: 'Package'
spec: {
  package: { name: 'LoanRegistry', constructorArgs: [...] }
}

Use for: Modular system components (Diamond facets)

PackageSystem - Complex multi-package systems

kind: 'PackageSystem'
spec: {
  system: { name: 'LendingApplication' },
  packages: [
    { name: 'LoanRegistry' },
    { name: 'LoanFunding' },
    { name: 'LoanRepayment' }
  ]
}

Use for: DeFi protocols, complex systems, DAOs

3. Package-Oriented Framework (POF)

POF enables:

  • ♾️ Unlimited size - Bypass 24KB contract size limit
  • 🔄 Upgradeable - Replace packages without full redeployment
  • 🧩 Modular - Reusable, composable components
  • 💾 Shared storage - All packages access same state through proxy
// Traditional: Monolithic (24KB max)
contract ComplexLending { /* 2000 lines */ }

// POF: Modular (unlimited)
contract LendingApplication (Diamond)
  ├── LoanRegistry
  ├── LoanFunding
  ├── LoanRepayment
  └── LoanTokenManager

API Reference

FeverDeployer

The main class for smart contract deployment.

Constructor

new FeverDeployer({
  wallet: WalletConfig,              // Required: How to sign transactions
  network: {                          // Required: Network connection
    chainId: number,
    rpcUrl: string
  },
  tracker?: DeploymentTracker,        // Optional: Track deployments
  artifacts?: ArtifactResolverConfig  // Optional: Where to find contract artifacts
})

Wallet Configuration

Private Key (Fastest)
wallet: {
  type: 'privateKey',
  value: process.env.PRIVATE_KEY!
}
Mnemonic (HD Wallets)
wallet: {
  type: 'mnemonic',
  value: 'abandon abandon abandon...',
  path: "m/44'/60'/0'/0/0"  // Optional BIP44 derivation path
}
Ethers.js Signer
wallet: {
  type: 'signer',
  signer: ethers.Wallet.createRandom()
}

Methods

deploy(manifest): Promise<DeploymentResult>

Deploy from a manifest object.

const result = await deployer.deploy({
  apiVersion: 'beta/v1',
  kind: 'Contract',
  metadata: { name: 'my-token', version: '1.0.0' },
  spec: {
    contract: {
      name: 'MyToken',
      constructorArgs: [
        { value: 'Token Name' },
        { value: 'TKN' }
      ]
    }
  }
})

console.log(`Deployed to: ${result.address}`)
deployFromFile(path): Promise<DeploymentResult>

Deploy from a YAML manifest file.

const result = await deployer.deployFromFile('./manifests/token.yaml')
getAddress(): Promise<string>

Get deployer's wallet address.

const address = await deployer.getAddress()
console.log(`Deploying from: ${address}`)
getChainId(): Promise<number>

Get connected network chain ID.

const chainId = await deployer.getChainId()
if (chainId !== 1337) throw new Error('Wrong network!')
getAvailableContracts(): string[]

List all available contracts in artifacts.

const contracts = deployer.getAvailableContracts()
console.log(`Available: ${contracts.join(', ')}`)
getDeployment(name, chainId?): Promise<DeploymentRecord | null>

Retrieve a previous deployment record.

const record = await deployer.getDeployment('MyToken', 1337)
if (record) {
  console.log(`Previously deployed to: ${record.address}`)
}
listDeployments(chainId?): Promise<DeploymentRecord[]>

List all deployments for a chain.

const deployments = await deployer.listDeployments(1337)
deployments.forEach(d => {
  console.log(`${d.contractName}: ${d.address}`)
})

Wallet Types

PrivateKeyWallet

import { PrivateKeyWallet } from '@fevertokens/sdk'

const wallet = new PrivateKeyWallet(
  '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
  provider
)

MnemonicWallet

import { MnemonicWallet } from '@fevertokens/sdk'

const wallet = new MnemonicWallet(
  'abandon abandon abandon...',
  provider,
  "m/44'/60'/0'/0/0"  // BIP44 path
)

SignerWallet

import { SignerWallet } from '@fevertokens/sdk'

const wallet = new SignerWallet(ethers.Wallet.createRandom())

Deployment Tracking

Track deployments for auditing and reference:

import { FileTracker } from '@fevertokens/sdk'

const deployer = new FeverDeployer({
  // ... other config
  tracker: new FileTracker('./.fever/deployments')
})

// Deployments automatically saved after each deploy

// Retrieve later
const record = await deployer.getDeployment('MyToken', 1337)
console.log(`Deployed to: ${record.address}`)

Examples

1. Simple ERC20 Deployment

import { FeverDeployer } from '@fevertokens/sdk'

async function deployToken() {
  const deployer = new FeverDeployer({
    wallet: { type: 'privateKey', value: process.env.PRIVATE_KEY! },
    network: { chainId: 1337, rpcUrl: 'http://localhost:8545' }
  })

  const result = await deployer.deploy({
    apiVersion: 'beta/v1',
    kind: 'Contract',
    metadata: { name: 'my-token', version: '1.0.0' },
    spec: {
      contract: {
        name: 'MyToken',
        constructorArgs: [
          { value: 'My Token' },
          { value: 'MTK' }
        ]
      }
    }
  })

  console.log(`✓ Deployed to: ${result.address}`)
  return result
}

deployToken().catch(console.error)

2. Lending Protocol (PackageSystem)

async function deployLendingSystem() {
  const deployer = new FeverDeployer({
    wallet: { type: 'privateKey', value: process.env.PRIVATE_KEY! },
    network: { chainId: 1337, rpcUrl: 'http://localhost:8545' }
  })

  const result = await deployer.deploy({
    apiVersion: 'beta/v1',
    kind: 'PackageSystem',
    metadata: { name: 'lending-v1', version: '1.0.0' },
    spec: {
      system: {
        name: 'LendingApplication',
        constructorArgs: [
          '$dependencies.packageController.address',  // Auto-injected!
          '$dependencies.packageViewer.address',
          '${ADMIN_ADDRESS}'  // From env
        ]
      },
      packages: [
        { name: 'LoanRegistry', functions: '*' },
        { name: 'LoanFunding', functions: '*' },
        { name: 'LoanRepayment', functions: '*' },
        { name: 'LoanTokenManager', functions: '*' }
      ],
      dependencies: {
        packageViewer: { name: 'PackageViewer' },
        packageController: { name: 'PackageController' }
      }
    }
  })

  console.log(`✓ System: ${result.address}`)
  console.log(`✓ Packages: ${result.packages.length}`)
  console.log(`✓ Gas: ${result.totalGasUsed}`)
}

deployLendingSystem().catch(console.error)

3. CI/CD Deployment

import { FeverDeployer, FileTracker } from '@fevertokens/sdk'

async function cicdDeploy() {
  const deployer = new FeverDeployer({
    wallet: { type: 'privateKey', value: process.env.DEPLOYER_KEY! },
    network: {
      chainId: parseInt(process.env.CHAIN_ID || '1'),
      rpcUrl: process.env.RPC_URL!
    },
    tracker: new FileTracker('./.fever/deployments'),
    artifacts: { combinedPath: './.fever/combined.json' }
  })

  // Verify network
  const chainId = await deployer.getChainId()
  if (chainId !== parseInt(process.env.CHAIN_ID!)) {
    throw new Error('Wrong network!')
  }

  // Deploy
  const result = await deployer.deployFromFile('./manifests/production.yaml')

  // Export for CI/CD
  console.log(`::set-output name=address::${result.address}`)
  console.log(`::set-output name=tx::${result.transactionHash}`)
}

cicdDeploy().catch(error => {
  console.error('Deployment failed:', error.message)
  process.exit(1)
})

4. Testing Contracts

import { FeverDeployer } from '@fevertokens/sdk'

describe('MyToken', () => {
  let deployer: FeverDeployer
  let tokenAddress: string

  beforeAll(async () => {
    deployer = new FeverDeployer({
      wallet: { type: 'privateKey', value: '0xac0974...' },
      network: { chainId: 1337, rpcUrl: 'http://localhost:8545' }
    })
  })

  it('should deploy MyToken', async () => {
    const result = await deployer.deploy({
      apiVersion: 'beta/v1',
      kind: 'Contract',
      spec: {
        contract: {
          name: 'MyToken',
          constructorArgs: [{ value: 'Test' }, { value: 'TEST' }]
        }
      }
    })

    expect(result.address).toBeDefined()
    tokenAddress = result.address
  })

  it('should retrieve deployment', async () => {
    const record = await deployer.getDeployment('MyToken', 1337)
    expect(record?.address).toBe(tokenAddress)
  })
})

Advanced Features

Environment Variables

Use ${VAR_NAME} in manifests:

spec: {
  contract: {
    name: 'MyContract',
    constructorArgs: [
      { value: '${ADMIN_ADDRESS}' },
      { value: '${INITIAL_SUPPLY}' }
    ]
  }
}

// Set in .env:
// ADMIN_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
// INITIAL_SUPPLY=1000000

Dependency Resolution

Automatically resolve addresses from previous deployments:

spec: {
  system: {
    name: 'App',
    constructorArgs: [
      '$dependencies.tokenManager.address',  // Auto-injected!
      '$dependencies.controller.address'
    ]
  },
  dependencies: {
    tokenManager: { name: 'TokenManager' },
    controller: { name: 'PackageController' }
  }
}

Custom Artifact Sources

// From file
deployer.setCombinedJsonPath('./.fever/combined.json')

// From direct data
const artifacts = {
  contracts: {
    MyToken: {
      abi: [...],
      bytecode: '0x...'
    }
  }
}
deployer.setCombinedJsonData(artifacts)

// From HTTP
const response = await fetch('https://api.example.com/artifacts')
deployer.setCombinedJsonData(await response.json())

Error Handling

try {
  const result = await deployer.deploy(manifest)
} catch (error) {
  if (error.code === 'NONCE_EXPIRED') {
    console.error('Check pending transactions')
  } else if (error.code === 'INSUFFICIENT_FUNDS') {
    console.error('Not enough balance for gas')
  } else {
    console.error('Deployment failed:', error.message)
  }
}

FAQ

Q: What's the difference between Contract, Package, and PackageSystem?

  • Contract: Regular smart contracts (ERC20, NFTs, etc.)
  • Package: POF facets designed to be composed into systems
  • PackageSystem: Complete system of coordinated packages

Q: How does POF work?

POF uses the Diamond pattern to split large contracts into modular packages. All packages share the same storage and are routed through a proxy, allowing:

  • Contracts larger than 24KB
  • Upgradeable packages without full redeployment
  • Modular, testable components

Q: Can I deploy to multiple chains?

Yes, create separate deployers:

const mainnet = new FeverDeployer({ network: { chainId: 1, rpcUrl: '...' } })
const polygon = new FeverDeployer({ network: { chainId: 137, rpcUrl: '...' } })

await mainnet.deploy(manifest)
await polygon.deploy(manifest)

Q: How do I track production deployments?

Use FileTracker:

tracker: new FileTracker('/var/lib/fever/deployments')

Q: How is this different from Fever CLI?

  • Fever CLI: Command-line tool (fever deploy -f manifest.yaml)
  • SDK: Programmatic API for Node.js/TypeScript

Both use the same deployment engine.


Support & Resources


License

FeverTokens Proprietary Base Code License v1.0

This SDK is licensed under the FeverTokens Proprietary License. See LICENSE.md for full terms.

Summary

  • ✅ Use as integrated component in your Product
  • ✅ Create Derivative Works with modifications
  • ❌ Cannot extract or reuse Base Code independently
  • ❌ Cannot reverse engineer or decompile
  • ❌ Cannot redistribute separately

For full license terms, see LICENSE.md


Made with ❤️ by the FeverTokens team