npm package: @fevertokens/sdk
Description: TypeScript SDK for Fever smart contract deployment and management
Author: FeverTokens
Latest version: 0.0.5

# @fevertokens/sdk

**TypeScript SDK for Fever smart contract deployment and management**

[![npm version](https://img.shields.io/npm/v/@fevertokens/sdk)](https://www.npmjs.com/package/@fevertokens/sdk)
[![License: Proprietary](https://img.shields.io/badge/License-Proprietary-blue.svg)](../../LICENSE.md)
[![Node Version](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org/)

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?](#why-fevertokenssdk)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [API Reference](#api-reference)
- [Examples](#examples)
- [Support](#support)

---

## 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)**

```typescript
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
```bash
npm install @fevertokens/sdk ethers
```

### yarn
```bash
yarn add @fevertokens/sdk ethers
```

### pnpm
```bash
pnpm add @fevertokens/sdk ethers
```

**Requirements:**
- Node.js >= 18
- ethers v6.x

---

## Quick Start

Deploy a simple contract in 3 minutes:

```typescript
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:

```typescript
// 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
```typescript
kind: 'Contract'
spec: {
  contract: { name: 'MyToken', constructorArgs: [...] }
}
```
**Use for:** ERC20, NFTs, utilities, or any regular contract

#### Package - POF packages
```typescript
kind: 'Package'
spec: {
  package: { name: 'LoanRegistry', constructorArgs: [...] }
}
```
**Use for:** Modular system components (Diamond facets)

#### PackageSystem - Complex multi-package systems
```typescript
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

```solidity
// 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

```typescript
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)
```typescript
wallet: {
  type: 'privateKey',
  value: process.env.PRIVATE_KEY!
}
```

##### Mnemonic (HD Wallets)
```typescript
wallet: {
  type: 'mnemonic',
  value: 'abandon abandon abandon...',
  path: "m/44'/60'/0'/0/0"  // Optional BIP44 derivation path
}
```

##### Ethers.js Signer
```typescript
wallet: {
  type: 'signer',
  signer: ethers.Wallet.createRandom()
}
```

#### Methods

##### `deploy(manifest): Promise<DeploymentResult>`

Deploy from a manifest object.

```typescript
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.

```typescript
const result = await deployer.deployFromFile('./manifests/token.yaml')
```

##### `getAddress(): Promise<string>`

Get deployer's wallet address.

```typescript
const address = await deployer.getAddress()
console.log(`Deploying from: ${address}`)
```

##### `getChainId(): Promise<number>`

Get connected network chain ID.

```typescript
const chainId = await deployer.getChainId()
if (chainId !== 1337) throw new Error('Wrong network!')
```

##### `getAvailableContracts(): string[]`

List all available contracts in artifacts.

```typescript
const contracts = deployer.getAvailableContracts()
console.log(`Available: ${contracts.join(', ')}`)
```

##### `getDeployment(name, chainId?): Promise<DeploymentRecord | null>`

Retrieve a previous deployment record.

```typescript
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.

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

### Wallet Types

#### PrivateKeyWallet
```typescript
import { PrivateKeyWallet } from '@fevertokens/sdk'

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

#### MnemonicWallet
```typescript
import { MnemonicWallet } from '@fevertokens/sdk'

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

#### SignerWallet
```typescript
import { SignerWallet } from '@fevertokens/sdk'

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

### Deployment Tracking

Track deployments for auditing and reference:

```typescript
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

```typescript
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)

```typescript
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

```typescript
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

```typescript
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:

```typescript
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:

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

### Custom Artifact Sources

```typescript
// 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

```typescript
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:

```typescript
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:

```typescript
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

- **Documentation**: [docs.fevertokens.app](https://docs.fevertokens.app)
- **GitHub**: [FeverTokens/fever-cli](https://github.com/FeverTokens/fever-cli)
- **Issues**: [GitHub Issues](https://github.com/FeverTokens/fever-cli/issues)
- **Discord**: [FeverTokens Community](https://discord.gg/fevertokens)

---

## License

**FeverTokens Proprietary Base Code License** v1.0

This SDK is licensed under the FeverTokens Proprietary License. See [LICENSE.md](../../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](../../LICENSE.md)

---

**Made with ❤️ by the FeverTokens team**