npm package: @lnfi-network/lnfi-sdk
Description: LnfiSdk is an SDK built on the **Lnfi Protocol**. It provides a unified interface for interacting with wallets that support **Nostr**, managing assets actions such as trading, transferring tokens, and placing/canceling orders.
Latest version: 1.0.3

# LnfiSdk

LnfiSdk is an SDK built on the **Lnfi Protocol**.
It provides a unified interface for interacting with wallets that support **Nostr**, managing assets actions such as trading, transferring tokens, and placing/canceling orders.

---

## Installation

```bash
npm install @lnfi-network/lnfi-sdk
```

---

## Quick Start

```javascript
import { LnfiSdk } from '@lnfi-network/lnfi-sdk';

// Initialize with browser Nostr extension
const lnfisdk = new LnfiSdk({
  signer: window.nostr // Required for operations
});

// Get balance
const balance = await lnfisdk.tokenApi.getBalance('user_address');

// Transfer tokens
await lnfisdk.token.transfer({
  tokenName: 'SATS',
  amount: 100,
  to: 'recipient_address'
});
```

---

## API Reference

### LnfiSdk Class

#### Constructor

```javascript
const lnfisdk = new LnfiSdk(options);
```

**Options:**
- `env` *(optional)*: Environment ('development' | 'production', default: 'production')
- `relay` *(optional)*: Nostr relay URL(s) - string or array (uses default relays if not specified)
- `signer` *(optional)*: Custom signer instance (see configuration details below)
- `poolOptions` *(optional)*: NostrPool configuration object
- `baseURL` *(optional)*: API base URL (default: 'https://api.lnfi.network')

#### Signer Configuration

**1. Using Browser Nostr Extension (Recommended)**
```javascript
const lnfisdk = new LnfiSdk({
  signer: window.nostr // Use browser Nostr extension
});
```

**2. Using LnfiNostr + Private Key**
```javascript
import { LnfiSdk, LnfiNostr } from '@lnfi-network/lnfi-sdk';

const nostrSigner = new LnfiNostr({ 
  privateKey: 'nsec1...' // or hex format private key
});

const lnfisdk = new LnfiSdk({
  signer: nostrSigner
});
```

**3. Using LnfiNostr + EVM Wallet**
```javascript
// Using default window.ethereum
const nostrSigner = new LnfiNostr({ 
  evm: true // uses window.ethereum
});

// Using custom provider (viem/wagmi walletClient)
const nostrSigner = new LnfiNostr({ 
  evm: walletClient // pass viem/wagmi walletClient directly
});

// Using ethers provider
const provider = new ethers.BrowserProvider(window.ethereum).provider;
const nostrSigner = new LnfiNostr({ 
  evm: provider // pass extracted raw provider
});

const lnfisdk = new LnfiSdk({
  signer: nostrSigner
});
```

**4. Using LnfiNostr + BTC Wallet**
```javascript
const nostrSigner = new LnfiNostr({ 
  btc: true // uses window.unisat, or pass custom provider
});

const lnfisdk = new LnfiSdk({
  signer: nostrSigner
});
```

**5. Default Behavior (No signer provided)**
```javascript
const lnfisdk = new LnfiSdk(); // No signer parameter
```
When no signer is provided, the SDK will automatically select in this priority:
1. `window.lnfi.nostr`
2. `window.okxwallet.nostr` 
3. `window.tokenpocket.nostr`
4. `window.alby.nostr`
5. `window.nostr`

If none are available, it will throw an error: "Nostr provider not available"

#### Core Methods

- `getPublicKey()` - Get current account public key
- `getConfig()` - Get environment configuration
- `getNostrPool()` - Get NostrPool instance
- `runCommand(command, sendTo, queryOnly)` - Execute Nostr command

---

### Market Operations (`lnfisdk.market`)

#### Command-based Trading Operations (via Nostr)

```javascript
// List a sell order
await lnfisdk.market.listOrder({
  side: 'sell',           // 'buy' | 'sell'
  amount: '100',          // Amount to trade
  price: '101',           // Price per unit
  buyOrSellTokenName: 'LN', // Token to buy/sell
  payTokenName: 'SATS'    // Payment token
});

// Take an existing order
await lnfisdk.market.takeOrder('order_id');

// Cancel an order
await lnfisdk.market.cancelOrder('order_id');

// Repair an order
await lnfisdk.market.repairOrder('order_id');
```

---

### Market API (`lnfisdk.marketApi`)

#### Query Market Data

```javascript
// Get available tokens for trading
const tokens = await lnfisdk.marketApi.getMarketTokenList();

// Get order book listings
const orders = await lnfisdk.marketApi.getMarketOrderListing({
  page: 1,
  count: 20,
  token: 'token_address',  // Optional
  type: 'buy'             // Optional: 'buy' | 'sell'
});

// Get order history
const history = await lnfisdk.marketApi.getOrderHistory({
  count: 20,
  page: 1,
  type: 'all',              // 'all' | 'buy' | 'sell'
  token: 'token_address',   // Optional
  eventId: 'event_id',      // Optional
  status: 'all',            // Order status filter
  address: 'user_address'   // Optional
});

// Get user's orders
const myOrders = await lnfisdk.marketApi.getMarketMyOrder({
  count: 20,
  page: 1,
  type: 'all',
  token: 'token_address',
  status: 'all',
  owner: 'user_address'  // Optional, defaults to current user
});

// Get price chart data
const kline = await lnfisdk.marketApi.getKline({
  tokenAddress: 'token_address',
  startDataTime: '2024-01-01',
  endDataTime: '2024-01-31'
});
```

---

### Token Operations (`lnfisdk.token`)

#### Command-based Token Operations (via Nostr)

```javascript
// Approve token spending
await lnfisdk.token.approve({
  tokenName: 'SATS',
  amount: 1000,
  approveTo: 'spender_address'
});

// Transfer tokens
await lnfisdk.token.transfer({
  tokenName: 'SATS',
  amount: 100,
  to: 'recipient_address'
});

// Add address to address book
await lnfisdk.token.addAddressBook({
  address: 'user_address',
  name: 'friendly_name'
});

// Query address book
const addressBook = await lnfisdk.token.queryAddressBook('npub_address');

// Deposit via Lightning Network
await lnfisdk.token.deposit({
  tokenName: 'SATS',
  amount: 1000,
  to: 'npub_address'  // Optional, defaults to current user
});

// Withdraw via Lightning Network
await lnfisdk.token.withdraw({
  tokenName: 'SATS',
  invoice: 'lnbc1000...'  // Lightning invoice
});

// Decode Lightning invoice
const invoiceDetails = await lnfisdk.token.decodeInvoice('lnbc1000...');
```

---

### Token API (`lnfisdk.tokenApi`)

#### Query Token Data

```javascript
// Get token balance
const balance = await lnfisdk.tokenApi.getBalance('user_address');

// Get available tokens
const tokens = await lnfisdk.tokenApi.getTokenList();

// Get token allowance
const allowance = await lnfisdk.tokenApi.getAllowance(
  'token_address', 
  'owner_address', 
  'spender_address'
);

// Get funding records (deposits/withdrawals)
const records = await lnfisdk.tokenApi.getFundingRecords({
  page: 1,
  count: 20,
  type: 'deposit',        // 'deposit' | 'withdrawal'
  tokenAddress: 'token_address',
  address: 'user_address',
  status: 'completed'
});

// Get token events (transfers, approvals)
const events = await lnfisdk.tokenApi.getTokenEvents({
  type: 'transfer',       // 'transfer' | 'approve'
  token: 'token_address',
  eventId: 'event_id',    // Optional
  address: 'user_address',
  page: 1,
  count: 20
});

// Get token holders
const holders = await lnfisdk.tokenApi.getHolders({
  assetId: 'asset_id',
  owner: 'owner_address', // Optional
  page: 1,
  count: 20
});

// Get specific holder info
const holder = await lnfisdk.tokenApi.getHolder('asset_id', 'owner_address');

// Get holder summary
const summary = await lnfisdk.tokenApi.getHolderSummary('asset_id');

// Get payee list
const payees = await lnfisdk.tokenApi.getPayeeList();
```

---

### Lock API (`lnfisdk.lock`)

```javascript
// Get locked tokens list
const locks = await lnfisdk.lock.getLockList({
  page: 1,
  count: 20,
  owner: 'user_address'
});
```

---

### FairMint API (`lnfisdk.fairmint`)

#### Staking and Fair Distribution

```javascript
// Get horoscope list
const horoscopes = await lnfisdk.fairmint.getHoroscopList({
  stakeId: 'stake_id',
  staked: true
});

// Get activity data
const activity = await lnfisdk.fairmint.getActivity();

// Get user information
const userInfo = await lnfisdk.fairmint.getUserInfo({
  owner: 'user_address',
  stakeId: 'stake_id'
});

// Get user list
const users = await lnfisdk.fairmint.getUserList({
  stakeId: 'stake_id',
  horoscopId: 'horoscope_id',
  page: 1,
  count: 20
});

// Get ranking summary
const ranking = await lnfisdk.fairmint.getRankingSummary({
  stakeId: 'stake_id',
  horoscopId: 'horoscope_id'
});

// Search ranking
const searchResult = await lnfisdk.fairmint.getSearchRanking({
  stakeId: 'stake_id',
  horoscopId: 'horoscope_id',
  ranking: 'ranking_value'
});

// Get block list
const blocks = await lnfisdk.fairmint.getBlockList({
  stakeId: 'stake_id',
  page: 1,
  count: 20,
  orderBy: 'field_name'
});

// Get block user list
const blockUsers = await lnfisdk.fairmint.getBlockUserList({
  stakeId: 'stake_id',
  blockId: 'block_id'
});
```

---

## LnfiNostr Class

Standalone class for Nostr identity management and signing.

### Initialization

```javascript
import { LnfiNostr } from '@lnfi-network/lnfi-sdk';

// Using Nostr private key
const nostr1 = new LnfiNostr({ 
  privateKey: 'nsec1...' // or hex string
});

// Using Ethereum wallet
const nostr2 = new LnfiNostr({ 
  evm: true // uses window.ethereum
});
// Or custom provider
const nostr3 = new LnfiNostr({ 
  evm: customEthereumProvider
});

// Using Bitcoin wallet
const nostr4 = new LnfiNostr({ 
  btc: true // uses window.unisat
});
// Or custom provider  
const nostr5 = new LnfiNostr({ 
  btc: customBitcoinProvider
});
```

### Methods

```javascript
// Sign a message
const signature = await nostr.signMessage('hello world');

// Get public key
const pubkey = await nostr.getPublicKey();

// Get private key
const privkey = await nostr.getPrivateKey();

// Sign Nostr event
const signedEvent = await nostr.signEvent(event);

// NIP-04 encryption
const encrypted = await nostr.nip04.encrypt(recipientPubkey, message);
```

---

## Usage Examples

### Complete Trading Example

```javascript
import { LnfiSdk } from '@lnfi-network/lnfi-sdk';

const lnfisdk = new LnfiSdk({ env: 'production' });

// Check balance before trading
const balance = await lnfisdk.tokenApi.getBalance();
console.log('Current balance:', balance);

// List a buy order
await lnfisdk.market.listOrder({
  side: 'buy',
  amount: '1000',
  price: '50',
  buyOrSellTokenName: 'TOKEN',
  payTokenName: 'SATS'
});

// Check order status
const myOrders = await lnfisdk.marketApi.getMarketMyOrder({
  count: 10,
  page: 1
});
console.log('My orders:', myOrders);
```

### Lightning Network Integration

```javascript
// Deposit SATS via Lightning
await lnfisdk.token.deposit({
  tokenName: 'SATS',
  amount: 10000
});

// Withdraw to Lightning invoice
await lnfisdk.token.withdraw({
  tokenName: 'SATS', 
  invoice: 'lnbc10000...'
});
```

---

## Utilities

The utils module provides complete nostr-tools functionality plus custom utility functions.

### Custom Utilities

```javascript
import { 
  NostrPool,
  getNostr,
  getBolt11,
  generateKeyPair, 
  decodePublicKey, 
  decodePrivateKey
} from '@lnfi-network/lnfi-sdk/utils';

// Custom NostrPool for enhanced relay management
const pool = new NostrPool(options, relays, signer);

// Get browser extension Nostr instance
// Auto-detects: lnfi.nostr -> okxwallet.nostr -> tokenpocket.nostr -> alby.nostr -> window.nostr
const nostr = getNostr();

// Generate new key pair with multiple formats
const keyPair = generateKeyPair();
// Returns: { pk_hex, pk_nsec, pubkey_hex, pubkey_npub }

// Decode public key (hex or npub format)
const pubKey = decodePublicKey("npub1...");
// Returns: { pubkey_hex, pubkey_npub }

// Decode private key (hex or nsec format)
const privKey = decodePrivateKey("nsec1...");
// Returns: { pk_hex, pk_nsec, pubkey_hex, pubkey_npub }

// Get bolt11 implementation (Node.js or browser)
const bolt11 = await getBolt11();
const decoded = bolt11.decode('lnbc1...');
```

### Nostr-tools Integration

All nostr-tools functions are re-exported and can be used directly:

```javascript
import { 
  nip04, nip19, SimplePool, getPublicKey, 
  getEventHash, getSignature, generatePrivateKey
} from '@lnfi-network/lnfi-sdk/utils';

// Use any nostr-tools function directly
const privateKey = generatePrivateKey();
const publicKey = getPublicKey(privateKey);
const npub = nip19.npubEncode(publicKey);
const encrypted = await nip04.encrypt(privateKey, publicKey, 'message');
```

---

## Development

```bash
# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build

# Run linting
npm run lint
```

---

## License

MIT