npm package: @lifestonelabs/tokensales
Description: Library for interacting with TokenSales contracts on Bitcoin Cash
Latest version: 1.0.9

# TokenSales Library

A TypeScript library for interacting with TokenSales contracts on Bitcoin Cash. This library provides a clean, framework-agnostic API for building and signing transactions that interact with TokenSales smart contracts.

## Installation

```bash
npm install @lifestonelabs/tokensales
```

## Signing Transactions

This library returns transaction objects with empty user input signatures. You can use WalletConnect, or any other signing method you prefer. The library includes an optional `createSignTransaction` helper for WalletConnect, but you're free to use your own signing implementation.

## Usage

### Setup

```typescript
import { 
  buyNFT, 
  createSignTransaction,
  getContractAddresses 
} from 'tokensales';
import { ElectrumNetworkProvider } from '@electrum-cash/network';
// OR use the high-level protocol package:
// import { ElectrumNetworkProvider } from '@electrum-cash/protocol';
import { SignClient } from '@walletconnect/sign-client';

// Initialize provider
const provider = new ElectrumNetworkProvider('mainnet');

// Note: The contract artifact is included in the library and compiled automatically
// Functions return transaction objects that you can sign with your preferred method
// 
// The library accepts any ElectrumNetworkProvider instance compatible with CashScript.
// You can use either @electrum-cash/network (low-level) or @electrum-cash/protocol (high-level).
```

### Purchase a Ticket

```typescript
import { buyNFT } from 'tokensales';

const wcTransactionObj = await buyNFT({
  electrumProvider: provider,
  usersAddress: 'bitcoincash:...',
  ticketMasterUtxo: tokenSaleUtxo, // TokenSale UTXO
  ticketUtxo: ticketUtxo,
  ticketType: '01', // '01', '02', or '03'
  isAdmin: false
});

// Sign the transaction with your preferred method (WalletConnect, etc.)
// Example with WalletConnect:
// const signClient = await SignClient.init({ ... });
// const result = await signClient.request({
//   chainId: 'bch:mainnet',
//   topic: session.topic,
//   request: {
//     method: 'bch_signTransaction',
//     params: JSON.parse(stringify(wcTransactionObj))
//   }
// });

// Broadcast transaction
// await provider.sendRawTransaction(result.signedTransaction);
```

### Modify TokenSale

```typescript
import { modifyTokenSale } from 'tokensales';

const wcTransactionObj = await modifyTokenSale({
  electrumProvider: provider,
  usersAddress: 'bitcoincash:...',
  tokenSaleUtxo: tokenSaleUtxo,
  userMintingUtxo: userMintingUtxo,
  priceType1: 1000n,
  priceType2: 2000n,
  priceType3: 0n,
  endSale: 950000
});

// Sign and broadcast transaction (see buyNFT example above)
```

### Burn TokenSale and Tickets

```typescript
import { burn } from 'tokensales';

const wcTransactionObj = await burn({
  electrumProvider: provider,
  usersAddress: 'bitcoincash:...',
  ticketMasterUtxo: tokenSaleUtxo, // TokenSale UTXO
  userMintingNFT: userMintingNFT,
  tickets: ticketsArray // Array of ticket UTXOs to burn
});

// Sign and broadcast transaction (see buyNFT example above)
```

### Add Satoshis to Minting NFT

```typescript
import { addSatoshis } from 'tokensales';

const wcTransactionObj = await addSatoshis({
  electrumProvider: provider,
  usersAddress: 'bitcoincash:...',
  userMintingNFT: userMintingNFT,
  additionalSatoshis: 10000n
});

// Sign and broadcast transaction (see buyNFT example above)
```

### Create TokenSale Listing

```typescript
import { createListing } from 'tokensales';

const wcTransactionObj = await createListing({
  electrumProvider: provider,
  usersAddress: 'bitcoincash:...',
  userMintingNFT: userMintingNFT,
  priceType1: 1000n,
  priceType2: 2000n,
  priceType3: 0n,
  endSale: 950000,
  adminPubKeyHash: '0000000000000000000000000000000000000000' // TokenSale creator/owners pubkeyhash. Sales revenue and admin capabilities (e.g. modify, burn) are controlled by this address. 40 hex chars = 20bytes
});

// Sign and broadcast transaction (see buyNFT example above)
```

### List Available Tickets

```typescript
import { listAvailableTickets } from 'tokensales';

const availableTickets = await listAvailableTickets({
  electrumProvider: provider,
  categoryID: 'your-token-category-id' // Hex string of the token category
});

// Returns array of ticket UTXOs that are available for purchase
// Throws error if no active TokenSale found or sale has ended
console.log(`Found ${availableTickets.length} available tickets`);
```

## API Reference

### Functions

#### `buyNFT(params: BuyNFTParams): Promise<WalletConnectTransactionObject>`

Purchase a ticket NFT from a TokenSale.

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `usersAddress: string` - User's Bitcoin Cash address
- `ticketMasterUtxo: Utxo` - TokenSale UTXO
- `ticketUtxo: Utxo` - Ticket UTXO to purchase
- `ticketType: '01' | '02' | '03'` - Ticket type
- `isAdmin: boolean` - Whether user is admin (uses minting NFT)

**Returns:** `Promise<WalletConnectTransactionObject>` - Transaction object ready for signing

#### `modifyTokenSale(params: ModifyTokenSaleParams): Promise<WalletConnectTransactionObject>`

Modify TokenSale parameters (prices, endSale).

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `usersAddress: string` - User's Bitcoin Cash address
- `tokenSaleUtxo: Utxo` - TokenSale UTXO to modify
- `userMintingUtxo: Utxo` - User's minting NFT
- `priceType1: number | bigint` - Price for type 1 tickets
- `priceType2: number | bigint` - Price for type 2 tickets
- `priceType3: number | bigint` - Price for type 3 tickets
- `endSale: number` - Block height when sale ends

**Returns:** `Promise<WalletConnectTransactionObject>` - Transaction object ready for signing

#### `burn(params: BurnParams): Promise<WalletConnectTransactionObject>`

Burn a TokenSale NFT and all associated tickets.

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `usersAddress: string` - User's Bitcoin Cash address
- `ticketMasterUtxo: Utxo` - TokenSale UTXO to burn (note: parameter name kept for backward compatibility)
- `userMintingNFT: Utxo` - User's minting NFT
- `tickets: Utxo[]` - Array of ticket UTXOs to burn

**Returns:** `Promise<WalletConnectTransactionObject>` - Transaction object ready for signing

#### `addSatoshis(params: AddSatoshisParams): Promise<WalletConnectTransactionObject>`

Add satoshis to a minting NFT.

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `usersAddress: string` - User's Bitcoin Cash address
- `userMintingNFT: Utxo` - Minting NFT to add satoshis to
- `additionalSatoshis: bigint` - Amount of satoshis to add

**Returns:** `Promise<WalletConnectTransactionObject>` - Transaction object ready for signing

#### `createListing(params: CreateListingParams): Promise<WalletConnectTransactionObject>`

Create a new TokenSale listing.

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `usersAddress: string` - User's Bitcoin Cash address
- `userMintingNFT: Utxo` - User's minting NFT
- `priceType1: bigint` - Price for type 1 tickets
- `priceType2: bigint` - Price for type 2 tickets
- `priceType3: bigint` - Price for type 3 tickets
- `endSale: number` - Block height when sale ends
- `adminPubKeyHash: string` - Admin public key hash (40 hex chars)

**Returns:** `Promise<WalletConnectTransactionObject>` - Transaction object ready for signing

#### `listAvailableTickets(params: ListAvailableTicketsParams): Promise<Utxo[]>`

List available tickets for purchase from an active TokenSale.

**Parameters:**
- `electrumProvider: ElectrumNetworkProvider` - Electrum provider instance (from `@electrum-cash/network` or `@electrum-cash/protocol`)
- `categoryID: string` - Token category ID (hex string) to filter tickets

**Returns:** `Promise<Utxo[]>` - Array of ticket UTXOs available for purchase

**Throws:**
- Error if no TokenSale found for the category
- Error if TokenSale has ended (current block height >= endSale block)
- Error if TokenSale commitment cannot be parsed

### Utilities

#### `compileContract(provider: ElectrumNetworkProvider, addressType?: 'p2sh32' | 'p2sh20'): Contract`

Compiles the TokenSales contract using the included artifact. This is called automatically by the transaction functions, but can be used directly if needed.

#### `createSignTransaction(signClient: any, connectedChain?: string): SignTransactionFunction`

**Optional helper** - Creates a WalletConnect-compatible sign transaction function. This is provided as a convenience, but you can use any signing method you prefer.

#### `parseTicketMasterCommitment(commitment: string): TicketMasterData | null`

Parses a TokenSale commitment string to extract sale data.

#### `formatBCH(satoshis: bigint | number | string): string`

Formats satoshis to BCH string with 8 decimal places.

#### `toTokenAddress(address: string): string`

Converts a regular Bitcoin Cash address to its token address equivalent.

### Contract Addresses

#### `getContractAddress(): string`

Gets the TokenSales contract address.

#### `getTokenAddress(): string`

Gets the TokenSales token address.

#### `getContractAddresses(): { contract: string; token: string }`

Gets both contract and token addresses.

#### `AddressTicketMaster: string`

Direct export of the TokenSales contract address.

#### `AddressTicketMasterToken: string`

Direct export of the TokenSales token address.

## Error Handling

All functions throw errors instead of using callbacks. Make sure to wrap function calls in try-catch blocks:

```typescript
try {
  const wcTransactionObj = await buyNFT(params);
  // Sign transaction with your preferred method
  // Then broadcast: await provider.sendRawTransaction(signedTx);
} catch (error) {
  console.error('Transaction building failed:', error);
  // Handle error appropriately
}
```

## TypeScript Support

This library is written in TypeScript and includes full type definitions. All types are exported and can be imported:

```typescript
import type { BuyNFTParams, WalletConnectTransactionObject } from 'tokensales';
```

## License

MIT