npm package: @lendara/sdk
Description: Lendara Protocol SDK - Investment protocol on Stellar/Soroban using Trustless Work
Latest version: 0.1.0

# Lendara SDK

TypeScript SDK for the Lendara investment protocol on Stellar/Soroban.

## Installation

```bash
cd sdk
npm install
npm run build
```

## Configuration

```typescript
import { LendaraClient } from "./src";

const client = new LendaraClient({
  network: "testnet",                    // "testnet" or "mainnet"
  trustlessWorkApiKey: "your-api-key",   // Get from https://app.trustlesswork.com
  // Optional overrides:
  // rpcUrl: "https://soroban-testnet.stellar.org",
  // trustlessWorkBaseUrl: "https://dev.api.trustlesswork.com",
});
```

## Quick Reference

### Templates

```typescript
// List all 5 sector templates
const templates = client.getTemplates();
// -> real-estate-rental, trade-finance, agricultural-lending, microfinance, event-finance

// Get a specific template
const template = client.getTemplate("microfinance");
console.log(template.timing.minInvestment);    // 100000000n (10 USDC)
console.log(template.timing.maxInvestors);      // 500
console.log(template.tokenization.suggestedRoiMin); // 12
```

### Role Mapping

```typescript
import type { RoleAddresses } from "./src";

const addresses: RoleAddresses = {
  operator: "GOPERATOR...",          // The entity doing the work
  verificationAgent: "GVERIFIER...", // Auditor/approver
  poolManager: "GMANAGER...",        // Releases funds
  arbitrator: "GARBITRATOR...",      // Resolves disputes
  platform: "GPLATFORM...",          // Collects fees
};

// Map to Trustless Work roles (with validation)
const { roles, warnings } = client.generateRoleMapping("microfinance", addresses);
// roles = { serviceProvider, approver, releaseSigner, disputeResolver, platformAddress }

if (warnings.length > 0) {
  console.warn(warnings); // e.g., "Operator and Verification Agent share the same address"
}
```

### Generate Escrow Config

```typescript
import { parseUsdc } from "./src";

const totalAmount = parseUsdc("10000");   // 10,000 USDC to raise
const returnAmount = parseUsdc("11500");  // 11,500 USDC expected (15% ROI)

const escrowConfig = client.generateEscrowConfig(
  "microfinance",
  totalAmount,
  returnAmount,
  roles,
  addresses.operator,
  "GVAULT_ADDRESS...",
  { platformFee: 2.5 }  // Optional override
);
// escrowConfig is ready to send to Trustless Work API
```

### Deploy Escrow

```typescript
const project = await client.createProject({
  templateId: "microfinance",
  name: "Kenya Micro-Loans Q2",
  description: "Micro-loans for small businesses",
  totalAmount: parseUsdc("10000"),
  roiPercentage: 15,
  addresses,
});

const escrow = await client.createEscrow(
  project,
  parseUsdc("10000"),
  parseUsdc("11500"),
  addresses,
  addresses.operator,
  "GVAULT_ADDRESS...",
);
// Returns { escrowContractId, unsignedXdr }
// Sign the XDR with a wallet, then:
await client.sendTransaction(signedXdr);
```

### Read Contract State

```typescript
// Vault overview
const vault = await client.getVaultOverview("CVAULT...");
console.log(vault.roiPercentage);        // 15
console.log(vault.totalUsdcDistributed); // 0n
console.log(vault.enabled);              // true

// Sale overview
const sale = await client.getSaleOverview("CSALE...");
console.log(sale.totalRaised);     // 5000_0000000n
console.log(sale.investorCount);   // 23

// Token balance
const balance = await client.getTokenBalance("CTOKEN...", "GINVESTOR...");

// Claim preview
const preview = await client.previewClaim("CVAULT...", "GINVESTOR...");
console.log(preview.usdcAmount);                 // 1150_0000000n
console.log(preview.vaultHasSufficientBalance);  // true
```

### TW Escrow Operations

```typescript
// Operator updates milestone status
await client.updateMilestoneStatus(
  escrowContractId,
  0,                      // milestone index
  "completed",
  "ipfs://QmEvidence...", // evidence URI
  addresses.operator
);

// Verification Agent approves
await client.approveMilestone(escrowContractId, 0, addresses.verificationAgent);

// Pool Manager releases funds
await client.releaseMilestoneFunds(escrowContractId, addresses.poolManager, 0);

// Dispute a milestone
await client.disputeMilestone(escrowContractId, 0, addresses.verificationAgent);
```

### Activity Reporter

```typescript
const reporter = await client.getReporterOverview("CREPORTER...");
console.log(reporter.totalReports);         // 5
console.log(reporter.totalAmountVerified);  // 3500_0000000n
```

## Utility Functions

```typescript
import { formatUsdc, parseUsdc, computeEvidenceHash } from "./src";

// Format stroops to human-readable USDC
formatUsdc(10_000_0000000n);    // "10000.00"
formatUsdc(1_500_0000000n, 4);  // "1500.0000"

// Parse human-readable USDC to stroops
parseUsdc("1000.50");  // 10005000000n

// Compute SHA-256 hash for evidence (Activity Reporter)
const file = await fetch("evidence.pdf").then(r => r.arrayBuffer());
const hash = await computeEvidenceHash(file);
// -> "a1b2c3d4..." (64 char hex string)
```

## Building Soroban Transactions

For write operations that need wallet signing:

```typescript
import { buildSorobanTransaction } from "./src";

// Build an unsigned transaction
const xdr = await buildSorobanTransaction(
  "https://soroban-testnet.stellar.org",
  "Test SDF Network ; September 2015",
  "CSALE_ADDRESS...",
  "buy",
  "GINVESTOR_PUBLIC_KEY...",
  [
    { type: "address", value: "GINVESTOR..." },   // payer
    { type: "address", value: "GINVESTOR..." },   // beneficiary
    { type: "i128", value: 1000_0000000n },        // amount
  ]
);

// Sign with wallet (e.g., Freighter)
const signedXdr = await signTransaction(xdr);

// Submit
await client.sendTransaction(signedXdr);
```

## Using TW Client Directly

If you need lower-level access to the Trustless Work API:

```typescript
import { TrustlessWorkClient } from "./src";

const tw = new TrustlessWorkClient({
  baseUrl: "https://dev.api.trustlesswork.com",
  apiKey: "your-key",
});

// Deploy escrow directly
const result = await tw.deployMultiReleaseEscrow(escrowConfig);

// Query escrows by role
const escrows = await tw.getEscrowsByRole("GADDRESS...", "approver");

// Get balances
const balances = await tw.getMultipleEscrowBalances(["CESCROW1...", "CESCROW2..."]);
```

## Module Structure

```
src/
├── index.ts           # All exports
├── client.ts          # LendaraClient (main entry point)
├── types/             # TypeScript interfaces
│   ├── config.ts      # LendaraConfig, Network
│   ├── escrow.ts      # TW escrow types
│   ├── contracts.ts   # Contract types (Sale, Vault, Reporter, etc.)
│   ├── templates.ts   # SectorTemplate interfaces
│   └── roles.ts       # Role mapping types
├── contracts/         # Read wrappers for each Soroban contract
│   ├── token-factory.ts
│   ├── token-sale.ts
│   ├── vault.ts
│   └── activity-reporter.ts
├── trustless-work/    # TW REST API wrapper
│   └── tw-client.ts
├── templates/         # Sector templates
│   ├── engine.ts      # TemplateEngine class
│   └── registry.ts    # 5 built-in templates
├── roles/             # Role mapping
│   └── mapper.ts      # RoleMapper class
└── utils/             # Utilities
    ├── soroban.ts     # Contract invocation (uses @stellar/stellar-sdk)
    └── format.ts      # USDC formatting, evidence hashing
```