# SDK Reference

### Install

```bash
npm install @spree-finance/spree-evm-sdk
```

### Configuration

All contract wrappers accept `BaseContractConfig`:

```typescript
import type { BaseContractConfig, Hex, TxOverrides } from '@spree-finance/spree-evm-sdk';

interface BaseContractConfig {
  rpcUrl: string;
  chainId: bigint;
  contractAddress: Hex;
  from: Hex;
  defaultGasPriceWei: bigint;
  defaultGasLimit: bigint;
}
```

### Types

```typescript
type Hex = `0x${string}`;

interface TxOverrides {
  gasPriceWei?: bigint;
  gasLimit?: bigint;
  valueWei?: bigint;
  maxFeePerGasWei?: bigint;           // EIP-1559
  maxPriorityFeePerGasWei?: bigint;   // EIP-1559
  txType?: 'legacy' | 'eip1559';
}
```

### Factory

Mint/redeem SP, manage vaults, whitelists, and rates.

```typescript
import { Factory } from '@spree-finance/spree-evm-sdk';
const factory = new Factory(config);
```

#### Write Methods

```typescript
// Vault management
factory.createVault(asset: Hex, assetToSharesRate: bigint, overrides?: TxOverrides): Promise<Hex>
factory.pauseVault(asset: Hex, overrides?): Promise<Hex>
factory.unpauseVault(asset: Hex, overrides?): Promise<Hex>

// Mint/Redeem
factory.mint(asset: Hex, amount: bigint, receiver: Hex, expectBasketMode: boolean, overrides?): Promise<Hex>
factory.requestToRedeem(asset: Hex, pointsAmount: bigint, receiver: Hex, expectBasketMode: boolean, overrides?): Promise<Hex>
factory.finalizeRedeem(account: Hex, overrides?): Promise<Hex>
factory.cancelRedeemRequest(overrides?): Promise<Hex>
factory.rejectRedeemRequest(account: Hex, overrides?): Promise<Hex>

// Configuration
factory.setMintRate(asset: Hex, mintRate: bigint, overrides?): Promise<Hex>
factory.setRedeemRate(asset: Hex, redeemRate: bigint, overrides?): Promise<Hex>
factory.setGlobalCap(limit: bigint, overrides?): Promise<Hex>
factory.setFeeReceiver(feeReceiver: Hex, overrides?): Promise<Hex>
factory.setMinRedeemRequest(min: bigint, overrides?): Promise<Hex>

// Whitelist
factory.addToMintWhitelist(account: Hex, overrides?): Promise<Hex>
factory.removeFromMintWhitelist(account: Hex, overrides?): Promise<Hex>
factory.addToRedeemWhitelist(account: Hex, overrides?): Promise<Hex>
factory.removeFromRedeemWhitelist(account: Hex, overrides?): Promise<Hex>

// Access control
factory.grantRole(role: Hex, account: Hex, overrides?): Promise<Hex>
factory.revokeRole(role: Hex, account: Hex, overrides?): Promise<Hex>

// Pause
factory.pause(overrides?): Promise<Hex>
factory.unpause(overrides?): Promise<Hex>
```

#### Read Methods

```typescript
factory.readMintRates(asset: Hex): Promise<bigint>
factory.readRedeemRates(asset: Hex): Promise<bigint>
factory.readGlobalCap(): Promise<bigint>
factory.readNumRegisteredAssets(): Promise<bigint>
factory.readRegisteredAssets(index: bigint): Promise<Hex>
factory.readVaults(asset: Hex): Promise<Hex>
factory.readMintWhitelist(account: Hex): Promise<boolean>
factory.readRedeemWhitelist(account: Hex): Promise<boolean>
factory.readPaused(): Promise<boolean>
factory.readHasRole(role: Hex, account: Hex): Promise<boolean>
factory.readGetWeights(): Promise<VaultWeight[]>
factory.readFeeReceiver(): Promise<Hex>
factory.readMinRedeemRequest(): Promise<bigint>
```

### Points

ERC-20 SP token with TWAB tracking and transfer whitelist.

```typescript
import { Points } from '@spree-finance/spree-evm-sdk';
const points = new Points(config);
```

#### Write Methods

```typescript
points.transfer(to: Hex, amount: bigint, overrides?): Promise<Hex>
points.transferFrom(from: Hex, to: Hex, amount: bigint, overrides?): Promise<Hex>
points.approve(spender: Hex, amount: bigint, overrides?): Promise<Hex>
points.mint(to: Hex, amount: bigint, overrides?): Promise<Hex>
points.burn(from: Hex, amount: bigint, overrides?): Promise<Hex>
points.addToTransferWhitelist(account: Hex, overrides?): Promise<Hex>
points.removeFromTransferWhitelist(account: Hex, overrides?): Promise<Hex>
```

#### Read Methods

```typescript
points.readBalanceOf(owner: Hex): Promise<bigint>
points.readTotalSupply(): Promise<bigint>
points.readAllowance(owner: Hex, spender: Hex): Promise<bigint>
points.readName(): Promise<string>
points.readSymbol(): Promise<string>
points.readDecimals(): Promise<bigint>
points.readIsTransferWhitelisted(account: Hex): Promise<boolean>
points.readTransferWhitelist(account: Hex): Promise<boolean>
points.readFactory(): Promise<Hex>
```

### SpreeVault4626

ERC-4626 yield vault with harvest, rebalance, and fee management.

```typescript
import { SpreeVault4626 } from '@spree-finance/spree-evm-sdk';
const vault = new SpreeVault4626(config);
```

#### Write Methods

```typescript
// ERC-4626 core
vault.deposit(assets: bigint, receiver: Hex, overrides?): Promise<Hex>
vault.mint(shares: bigint, receiver: Hex, overrides?): Promise<Hex>
vault.withdraw(assets: bigint, receiver: Hex, owner: Hex, overrides?): Promise<Hex>
vault.redeem(shares: bigint, receiver: Hex, owner: Hex, overrides?): Promise<Hex>

// Strategy
vault.harvest(overrides?): Promise<Hex>
vault.rebalance(overrides?): Promise<Hex>
vault.emergencyWithdrawAll(overrides?): Promise<Hex>

// Admin
vault.setFees(mintFeeBps: bigint, redeemFeeBps: bigint, feeReceiver: Hex, overrides?): Promise<Hex>
vault.setAdapter(adapter: Hex, overrides?): Promise<Hex>
vault.updateParameters(minIdleBufferBps: bigint, maxUtilizationBps: bigint, overrides?): Promise<Hex>
vault.setTransferWhitelist(account: Hex, allowed: boolean, overrides?): Promise<Hex>
vault.pause(overrides?): Promise<Hex>
vault.unpause(overrides?): Promise<Hex>
```

#### Read Methods

```typescript
vault.readConvertToShares(assets: bigint): Promise<bigint>
vault.readConvertToAssets(shares: bigint): Promise<bigint>
vault.readVaultHealth(): Promise<VaultHealth>
vault.readTotalAssets(): Promise<bigint>
vault.readBalanceOf(account: Hex): Promise<bigint>
vault.readFeeConfiguration(): Promise<FeeConfiguration>
vault.readLiquidityParameters(): Promise<LiquidityParameters>
vault.readMaxDeposit(receiver: Hex): Promise<bigint>
vault.readMaxRedeem(owner: Hex): Promise<bigint>
vault.readPaused(): Promise<boolean>
```

#### Interfaces

```typescript
interface VaultHealth {
  totalAssets: bigint;
  idleAssets: bigint;
  deployedAssets: bigint;
  idlePercentage: bigint;
  utilization: bigint;
  isBalanced: boolean;
}

interface FeeConfiguration {
  mintFee: bigint;
  redeemFee: bigint;
  receiver: Hex;
}

interface LiquidityParameters {
  minIdle: bigint;
  maxUtil: bigint;
  reserve: bigint;
}
```

### BonusRewardsVault

Epoch-based bonus reward distribution.

```typescript
import { BonusRewardsVault } from '@spree-finance/spree-evm-sdk';
const rewards = new BonusRewardsVault(config);
```

#### Write Methods

```typescript
rewards.claimBonus(epochId: bigint, overrides?): Promise<Hex>
rewards.claimBonusBatch(epochIds: bigint[], overrides?): Promise<Hex>
rewards.takeTVLSnapshot(overrides?): Promise<Hex>
rewards.registerPartner(partner: Hex, overrides?): Promise<Hex>
rewards.harvest(overrides?): Promise<Hex>
rewards.recordHarvest(vault: Hex, amount: bigint, overrides?): Promise<Hex>
rewards.setRewardPolicy(minHold: bigint, epochSeconds: bigint, overrides?): Promise<Hex>
rewards.setAllowedVault(vault: Hex, allowed: boolean, overrides?): Promise<Hex>
rewards.registerPointsFactory(factory: Hex, brandedToken: Hex, active: boolean, overrides?): Promise<Hex>
rewards.pause(overrides?): Promise<Hex>
rewards.unpause(overrides?): Promise<Hex>
```

#### Read Methods

```typescript
rewards.readGetCurrentEpochId(): Promise<bigint>
rewards.readGetClaimableEpochs(user: Hex, maxEpochs: bigint): Promise<bigint[]>
rewards.readBonusEstimateForEpoch(user: Hex, epochId: bigint): Promise<bigint>
rewards.readGetTVLHistory(): Promise<TVLSnapshot[]>
rewards.readGetPartnerRevenue(partner: Hex): Promise<bigint>
rewards.readGetEpochBounds(epochId: bigint): Promise<EpochBounds>
rewards.readGetEpochHarvest(epochId: bigint): Promise<EpochHarvest>
rewards.readHasClaimedEpoch(user: Hex, epochId: bigint): Promise<boolean>
rewards.readGetAllPartners(): Promise<Hex[]>
rewards.readPaused(): Promise<boolean>
```

#### Interfaces

```typescript
interface TVLSnapshot { timestamp: bigint; tvl: bigint; }
interface EpochBounds { start: bigint; end: bigint; }
interface EpochHarvest { amount: bigint; timestamp: bigint; tvlAtHarvest: bigint; }
interface PartnerRevenue { total: bigint; lastUpdated: bigint; }
```

### PythPriceOracle

Pyth Network price feed integration.

```typescript
import { PythPriceOracle } from '@spree-finance/spree-evm-sdk';
const oracle = new PythPriceOracle(config);
```

#### Write Methods

```typescript
oracle.setPriceFeed(asset: Hex, feed: Hex, overrides?): Promise<Hex>
oracle.setPythSource(pythOracle: Hex, overrides?): Promise<Hex>
```

#### Read Methods

```typescript
oracle.readGetPrice(asset: Hex): Promise<bigint>
oracle.readGetPriceNoOlderThan(asset: Hex, age: bigint): Promise<bigint>
oracle.readGetPriceUnsafe(asset: Hex): Promise<bigint>
oracle.readPriceAvailable(asset: Hex): Promise<boolean>
```

### PendingSPVault

Campaign-based pSP distribution and settlement.

```typescript
import { PendingSPVault } from '@spree-finance/spree-evm-sdk';
const psp = new PendingSPVault(config);
```

#### Write Methods

```typescript
psp.createCampaign(name, admin, maxTotalSupply, maxMintPerUser, dailyMintLimit, startTime, endTime, vestingPeriod, overrides?): Promise<Hex>
psp.fundCampaign(campaignId: bigint, amount: bigint, overrides?): Promise<Hex>
psp.setCampaignActive(campaignId: bigint, active: boolean, overrides?): Promise<Hex>
psp.setCampaignAdmin(campaignId: bigint, admin: Hex, overrides?): Promise<Hex>
psp.setMinter(campaignId: bigint, minter: Hex, allowed: boolean, overrides?): Promise<Hex>
psp.mint(campaignId: bigint, to: Hex, amount: bigint, overrides?): Promise<Hex>
psp.mintBoosted(campaignId: bigint, to: Hex, baseAmount: bigint, overrides?): Promise<Hex>
psp.settle(campaignId: bigint, user: Hex, overrides?): Promise<Hex>
psp.expire(campaignId: bigint, user: Hex, overrides?): Promise<Hex>
psp.transferWithCampaign(campaignId: bigint, from: Hex, to: Hex, amount: bigint, overrides?): Promise<Hex>
```

#### Read Methods

```typescript
psp.readGetCampaign(campaignId: bigint): Promise<Campaign>
psp.readBalanceOfCampaign(campaignId: bigint, user: Hex): Promise<bigint>
psp.readGetCampaignAvailableBudget(campaignId: bigint): Promise<bigint>
psp.readGetUserCampaigns(user: Hex): Promise<bigint[]>
```

### SpreeStatusRegistry

Tier and status management for loyalty programs.

```typescript
import { SpreeStatusRegistry } from '@spree-finance/spree-evm-sdk';
const registry = new SpreeStatusRegistry(config);
```

#### Write Methods

```typescript
registry.createNamespace(name: string, overrides?): Promise<Hex>
registry.setTierConfig(namespace: bigint, tier: bigint, config: { spThreshold: bigint, holdingPeriod: bigint, boostMultiplier: bigint }, overrides?): Promise<Hex>
registry.setMaxTier(namespace: bigint, maxTier: bigint, overrides?): Promise<Hex>
registry.updateTier(namespace: bigint, user: Hex, overrides?): Promise<Hex>
registry.batchUpdateTiers(namespace: bigint, users: Hex[], overrides?): Promise<Hex>
registry.setUserTier(namespace: bigint, user: Hex, tier: bigint, overrides?): Promise<Hex>
registry.setTierByOracle(namespace: bigint, user: Hex, tier: bigint, overrides?): Promise<Hex>
```

#### Read Methods

```typescript
registry.readGetTier(namespace: bigint, user: Hex): Promise<bigint>
registry.readGetStatus(namespace: bigint, user: Hex): Promise<Status>
registry.readGetBoostMultiplier(namespace: bigint, user: Hex): Promise<bigint>
```

### BoostEngine

Boost multiplier calculations for campaigns and tiers.

```typescript
import { BoostEngine } from '@spree-finance/spree-evm-sdk';
const boost = new BoostEngine(config);
```

#### Write Methods

```typescript
boost.setNamespaceMultipliers(namespace: bigint, multipliers: bigint[], overrides?): Promise<Hex>
boost.setCampaignBoost(campaignId: bigint, config: {
  baseMultiplier: bigint,
  earlyBirdBonus: bigint,
  earlyBirdCount: bigint,
  loyaltyBonus: bigint,
  referralBonus: bigint,
  maxPerUser: bigint,
  cooldownSeconds: bigint,
}, overrides?): Promise<Hex>
boost.recordBoostApplication(campaignId: bigint, user: Hex, overrides?): Promise<Hex>
```

#### Read Methods

```typescript
boost.readGetMultiplier(campaignId: bigint, user: Hex): Promise<bigint>
boost.readGetTierMultiplier(namespace: bigint, tier: bigint): Promise<bigint>
boost.readCalculateBoostedReward(campaignId: bigint, user: Hex, baseAmount: bigint): Promise<bigint>
```

### Additional Modules

#### ClientOnboarding

Deploy brand infrastructure:

```typescript
import { ClientOnboarding } from '@spree-finance/spree-evm-sdk';

const onboarding = new ClientOnboarding({ apiBaseUrl: 'https://api.stg.spree.finance/api/v1' });

// Deploy a new brand
const taskId = await onboarding.deploy({ brandName: 'acme', chainId: 84532n });

// Poll for completion
const result = await onboarding.pollTask(taskId);

// Or deploy and wait in one call
const contracts = await onboarding.deployAndWait({ brandName: 'acme', chainId: 84532n });

// Query deployed contracts
const deployed = await onboarding.getDeployedContracts('acme');
const brands = await onboarding.listBrands();
const brand = await onboarding.getBrand('acme');
const tasks = await onboarding.listTasks();
const contractList = await onboarding.listContracts();
```

#### ContractRegistry

Query deployed factories and contracts:

```typescript
import { ContractRegistry } from '@spree-finance/spree-evm-sdk';

const registry = new ContractRegistry({ apiBaseUrl: 'https://api.stg.spree.finance/api/v1' });

const factories = await registry.listFactories();
const factory = await registry.getFactoryById('factory-id');
const byChain = await registry.getFactoriesByChainId(84532n);
const contracts = await registry.getContractsByChainId(84532n);
```

#### ERC20

Generic ERC-20 operations (for stablecoin approvals before minting):

```typescript
import { ERC20 } from '@spree-finance/spree-evm-sdk';

const usdc = new ERC20(config); // config.contractAddress = USDC address

const approveTx = await usdc.approve('0xFactoryAddress', 100_000_000n);
const transferTx = await usdc.transfer('0xRecipient', 50_000_000n);
const balance = await usdc.readBalanceOf('0xAddress');
```

### Nonce Caching

Build multiple transactions without repeated RPC calls for nonce:

```typescript
const factory = new Factory(config);

factory.enableNonceCache();

const tx1 = await factory.mint(asset, amount1, receiver, false);
const tx2 = await factory.mint(asset, amount2, receiver, false);
const tx3 = await factory.setMintRate(asset, rate);
// tx1 nonce=N, tx2 nonce=N+1, tx3 nonce=N+2

factory.disableNonceCache();
```

#### Manual Nonce

```typescript
factory.setNonce(42n);
const tx = await factory.mint(asset, amount, receiver, false); // nonce = 42
factory.resetNonceCache();
```

### Gas Overrides

Pass per-transaction gas parameters:

```typescript
const tx = await factory.mint(asset, amount, receiver, false, {
  gasLimit: 300_000n,
  gasPriceWei: 2_000_000_000n,
});

// EIP-1559
const tx1559 = await factory.mint(asset, amount, receiver, false, {
  txType: 'eip1559',
  maxFeePerGasWei: 3_000_000_000n,
  maxPriorityFeePerGasWei: 1_000_000_000n,
});
```

### Calldata Encoding

Encode function calls without building a full transaction:

```typescript
const calldata = factory.encodeCall('mint', [asset, amount, receiver, false]);
// Use for multicall, batch operations, or custom transaction builders
```

### Brand Configuration

```typescript
import { getBrandConfig, getContractsForBrand, getChildBrands } from '@spree-finance/spree-evm-sdk';

const config = getBrandConfig('spree');
const contracts = getContractsForBrand('spree', 84532n);
const children = getChildBrands('spree'); // child brand IDs
```

### Error Classes

```typescript
import { RpcError, NetworkError } from '@spree-finance/spree-evm-sdk';

// RpcError: JSON-RPC level errors (reverts, invalid params)
//   .code: number | undefined
//   .data: unknown | undefined

// NetworkError: Fetch/connection failures
//   .cause: Error | undefined
```

Additional error classes from the `ClientOnboarding` module:

```typescript
import { DeploymentConflictError, PollingTimeoutError } from '@spree-finance/spree-evm-sdk';

// DeploymentConflictError: brand already deployed
// PollingTimeoutError: deployAndWait/pollTask exceeded timeout
```
