# SDK

## SDK

The Risk Protocol SDK is a TypeScript library for interacting with Risk Protocol's core smart contracts and services. Built on ethers.js v6, it provides a complete interface for token management, vault operations, rebalancing, and price estimation.

### Installation

```bash
npm install risk-contracts
# or
yarn add risk-contracts
## Note that it's not published yet, the above is a placeholder
```

### Quick Start

#### Server-Side (Node.js)

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';

const config: RiskSdkConfig = {
  serverProvider: {
    rpcUrl: "https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY",
    privateKey: "YOUR_PRIVATE_KEY"
  },
  network: {
    name: "sepolia",
    chainId: 11155111
  },
  tokenFactory: {
    address: "0x8888cF3da8E6Fb30bEEcD9dC1dd220060c2969DC"
  },
  smartToken: {
    one: "0x...",  // RiskON token address
    two: "0x..."   // RiskOFF token address
  },
  orchestrator: {
    address: "0x..."
  },
  apiUrl: "https://api.riskprotocol.com"
};

const sdk = new RiskContracts(config);
```

#### Client-Side (Browser with Wallet)

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';
import { ethers } from 'ethers';

// Connect to user's wallet
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

const config: RiskSdkConfig = {
  clientProvider: {
    provider: provider,
    signer: signer
  },
  network: {
    name: "sepolia",
    chainId: 11155111
  },
  tokenFactory: {
    address: "0x..."
  },
  smartToken: {
    one: "0x...",
    two: "0x..."
  },
  orchestrator: {
    address: "0x..."
  },
  apiUrl: "https://api.riskprotocol.com"
};

const sdk = new RiskContracts(config);
```

### Configuration

The SDK requires a configuration object that specifies network settings, contract addresses, and provider details.

```typescript
interface RiskSdkConfig {
  // Provider (choose one)
  serverProvider?: {
    rpcUrl: string;
    privateKey: string;
  };
  clientProvider?: {
    provider: ethers.BrowserProvider;
    signer: ethers.JsonRpcSigner;
  };

  // Network configuration
  network: {
    name: string;
    chainId: number;
  };

  // Contract addresses
  tokenFactory: {
    address: string;
  };
  smartToken: {
    one: string;    // RiskON address
    two: string;    // RiskOFF address
  };
  orchestrator: {
    address: string;
  };

  // Optional: API URL for NTV price estimates
  apiUrl?: string;
}
```

**Important:** Provide either `serverProvider` or `clientProvider`, not both.

### Core Concepts

#### SDK Structure

The SDK exposes five main modules:

* **tokenFactory** - Core token operations, management fees, and rebalancing
* **smartToken** - ERC-4626 vault operations (deposits, withdrawals, transfers)
* **orchestrator** - Scheduled operations and Balancer pool management
* **balancerHelper** - Balancer pool calculations and swap estimations
* **priceEstimates** - Price discovery and slippage calculations

#### Working with Amounts

All token amounts in the SDK use **wei units** (BigInt). Use ethers.js utilities for conversion:

```typescript
import { ethers } from 'ethers';

// Convert to wei
const amount = ethers.parseEther("1.5");  // 1500000000000000000n

// Convert from wei
const readable = ethers.formatEther(amount);  // "1.5"

// For tokens with different decimals
const usdcAmount = ethers.parseUnits("100", 6);  // 6 decimals
```

#### Smart Tokens

Risk Protocol uses two smart tokens: **RiskON** (index 0) and **RiskOFF** (index 1). Most SmartToken methods accept an optional `contract` parameter:

```typescript
// RiskON 
await sdk.smartToken.balanceOf(address, 0);

// RiskOFF 
await sdk.smartToken.balanceOf(address, 1);
```

### Common Workflows

#### 1. Deposit Tokens

```typescript
import { ethers } from 'ethers';

const depositAmount = ethers.parseEther("100");
const userAddress = "0x...";

// 1. Preview the deposit
const sharesReceived = await sdk.smartToken.transaction.previewDeposit(
  depositAmount.toString(),
  0  // RiskON
);

console.log(`Will receive ${ethers.formatEther(sharesReceived)} shares`);

// 2. Approve token spending (get smart token address first)
const baseToken = await sdk.tokenFactory.getBaseToken();
const riskOnAddress = await sdk.tokenFactory.getSmartTokenAddress(0);
const erc20 = new ethers.Contract(
  baseToken,
  ['function approve(address,uint256) returns (bool)'],
  signer
);

const approveTx = await erc20.approve(
  riskOnAddress,
  depositAmount
);
await approveTx.wait();

// 3. Execute deposit
const depositTx = await sdk.smartToken.transaction.deposit(
  depositAmount.toString(),
  userAddress,
  0
);
await depositTx.wait();

console.log('Deposit successful!');
```

#### 2. Withdraw Tokens

```typescript
import { ethers } from 'ethers';

const withdrawAmount = ethers.parseEther("50");
const userAddress = "0x...";

// 1. Preview withdrawal
const assetsReceived = await sdk.smartToken.transaction.previewWithdraw(
  withdrawAmount.toString(),
  0
);

console.log(`Will receive ${ethers.formatEther(assetsReceived)} assets`);

// 2. Execute withdrawal
const withdrawTx = await sdk.smartToken.transaction.withdraw(
  withdrawAmount.toString(),
  userAddress,
  userAddress,
  0
);
await withdrawTx.wait();

console.log('Withdrawal successful!');
```

#### 3. Check Balances and Fees

```typescript
import { ethers } from 'ethers';

const userAddress = "0x...";

// Get share balance (RiskON)
const shares = await sdk.smartToken.balanceOf(userAddress, 0);
console.log(`Shares: ${ethers.formatEther(shares)}`);

// Get management fee rate
const feeRate = await sdk.tokenFactory.managementFees.getRate();
const feeRateBps = Number(feeRate) / 1e14;  // Convert to basis points
console.log(`Management fee: ${feeRateBps} bps`);

// Check if fees are active
const isActive = await sdk.tokenFactory.managementFees.isFeeActive();
console.log(`Fees active: ${isActive}`);
```

#### 4. Estimate Swap Outputs

```typescript
import { ethers } from 'ethers';

const poolAddress = "0x...";
const riskOnAddress = await sdk.tokenFactory.getSmartTokenAddress(0);
const riskOffAddress = await sdk.tokenFactory.getSmartTokenAddress(1);
const amountIn = ethers.parseEther("10");

// Estimate swap output (RiskON → RiskOFF)
const expectedOut = await sdk.balancerHelper.getExpectedAmountOut(
  poolAddress,
  riskOnAddress,   // RiskON
  riskOffAddress,  // RiskOFF
  amountIn
);

console.log(`Swapping 10 RiskON`);
console.log(`Expected output: ${ethers.formatEther(expectedOut)} RiskOFF`);

```

####

### Error Handling

Always wrap SDK calls in try-catch blocks:

```typescript
try {
  const tx = await sdk.smartToken.transaction.deposit(
    amount.toString(),
    recipient,
    0
  );
  await tx.wait();
} catch (error) {
  if (error.code === 'INSUFFICIENT_FUNDS') {
    console.error('Insufficient funds for gas');
  } else if (error.code === 'CALL_EXCEPTION') {
    console.error('Transaction reverted:', error.reason);
  } else {
    console.error('Transaction failed:', error.message);
  }
}
```

### Best Practices

#### 1. Always Preview Before Executing

```typescript
// Always preview first to show users what they'll receive
const preview = await sdk.smartToken.transaction.previewDeposit(amount, 0);
console.log(`You will receive ${ethers.formatEther(preview)} shares`);

```

#### 2. Check Maximum Limits

```typescript
const maxDeposit = await sdk.smartToken.transaction.maxDeposit(address, 0);

if (BigInt(amount) > maxDeposit) {
  throw new Error(`Amount exceeds maximum: ${ethers.formatEther(maxDeposit)}`);
}
```

### TypeScript Support

The SDK is fully typed. Import types as needed:

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';
import type { ethers } from 'ethers';

// All methods return properly typed values
const balance: bigint = await sdk.smartToken.balanceOf(address, 0);
```

### Next Steps

* See the API Reference for complete method documentation
