# Compra y venta de un token

Una vez que se lanza un token, los usuarios pueden comprar y vender en la curva de vinculación hasta que se alcance el objetivo de recaudación. Esta sección cubre cómo integrar la funcionalidad de trading.

## Cómo funciona el trading con curva de vinculación

LaunchLab utiliza curvas de vinculación para determinar los precios de los tokens según la oferta y la demanda:

* **Comprar** aumenta el precio: cada compra mueve el precio hacia arriba a lo largo de la curva
* **Vender** disminuye el precio: cada venta mueve el precio hacia abajo a lo largo de la curva
* **Descubrimiento de precios** — los compradores tempranos obtienen precios más bajos, creando incentivo para la participación temprana

El trading continúa hasta `totalFundRaisingB` se hayan recaudado tokens de cotización por ese valor, en cuyo punto el pool migra a un AMM de Raydium.

## Comprar tokens

Usa `buyToken()` para comprar tokens con tokens de cotización (por ejemplo, SOL).

```typescript
import { TxVersion } from '@raydium-io/raydium-sdk-v2'
import { initSdk } from './config'
import { PublicKey } from '@solana/web3.js'
import BN from 'bn.js'

const buyTokens = async () => {
  const raydium = await initSdk()

  const { execute, extInfo } = await raydium.launchpad.buyToken({
    mintA: new PublicKey('token-mint-address'),
    buyAmount: new BN(1_000_000_000),  // 1 SOL in lamports
    slippage: new BN(100),             // 1% slippage
    txVersion: TxVersion.V0,
  })

  console.log('Expected tokens:', extInfo.decimalOutAmount.toString())

  const { txId } = await execute({ sendAndConfirm: true })
  console.log('Transaction:', txId)
}
```

### Parámetros de compra

| Parámetro         | Tipo      | Requerido | Descripción                                                                 |
| ----------------- | --------- | --------- | --------------------------------------------------------------------------- |
| `mintA`           | PublicKey | Sí        | La mint del token a comprar.                                                |
| `mintAProgram`    | PublicKey | No        | Programa del token (SPL o Token-2022). El SDK lo detecta si se omite.       |
| `buyAmount`       | BN        | Sí        | Cantidad de tokens de cotización a gastar (por ejemplo, lamports para SOL). |
| `poolInfo`        | object    | No        | Datos del estado del pool. El SDK los obtiene si se omiten.                 |
| `configInfo`      | object    | No        | Datos de configuración global. El SDK los obtiene si se omiten.             |
| `platformFeeRate` | BN        | No        | Tasa de comisión de la plataforma. El SDK la obtiene si se omite.           |
| `slippage`        | BN        | No        | Deslizamiento máximo en bps (`100 = 1%`). Predeterminado: `100`.            |
| `minMintAAmount`  | BN        | No        | Tokens mínimos a recibir. El SDK lo calcula si se omite.                    |

### Comprar una cantidad exacta de tokens

Usa `buyTokenExactOut()` para especificar exactamente cuántos tokens quieres recibir.

```typescript
const { execute, extInfo } = await raydium.launchpad.buyTokenExactOut({
  programId: LAUNCHPAD_PROGRAM,
  mintA,
  poolInfo,

  // Specify exact output
  outAmount: new BN('1000000000000'),  // Exact tokens to receive
  maxBuyAmount: new BN('2000000000'),  // Maximum quote tokens to spend

  slippage: new BN(100),
  txVersion: TxVersion.V0,
})
```

## Vender tokens

Usa `sellToken()` para vender tokens a cambio de tokens de cotización.

```typescript
const sellTokens = async () => {
  const raydium = await initSdk()

  const mintA = new PublicKey('token-mint-address')
  const sellAmount = new BN('500000000000')  // Tokens to sell

  const { execute, extInfo } = await raydium.launchpad.sellToken({
    programId: LAUNCHPAD_PROGRAM,

    // Token to sell
    mintA,

    // Sell parameters
    sellAmount,             // Amount of tokens to sell
    slippage: new BN(100),  // 1% slippage tolerance

    txVersion: TxVersion.V0,
  })

  console.log('Expected quote tokens:', extInfo.outAmount.toString())

  await execute({ sendAndConfirm: true })
}
```

### Parámetros de venta

| Parámetro    | Tipo      | Requerido | Descripción                                                            |
| ------------ | --------- | --------- | ---------------------------------------------------------------------- |
| `mintA`      | PublicKey | Sí        | La mint del token a vender.                                            |
| `sellAmount` | BN        | Sí        | Cantidad de tokens a vender.                                           |
| `poolInfo`   | object    | No        | Datos del estado del pool. El SDK los obtiene si se omiten.            |
| `slippage`   | BN        | No        | Deslizamiento máximo en bps (`100 = 1%`). Predeterminado: `100`.       |
| `minAmountB` | BN        | No        | Tokens de cotización mínimos a recibir. El SDK lo calcula si se omite. |

### Vender por una cantidad exacta de cotización

Usa `sellTokenExactOut()` para especificar exactamente cuántos tokens de cotización quieres recibir.

```typescript
const { execute } = await raydium.launchpad.sellTokenExactOut({
  programId: LAUNCHPAD_PROGRAM,
  mintA,
  poolInfo,

  // Specify exact output
  inAmount: new BN('1000000000'),        // Exact quote tokens to receive
  maxSellAmount: new BN('600000000000'), // Maximum tokens to sell

  slippage: new BN(100),
  txVersion: TxVersion.V0,
})
```

## Avanzado: Cálculo de cotizaciones

Usa la `Curve` utilidad para calcular salidas esperadas antes de ejecutar operaciones (por ejemplo, mostrar montos esperados en la UI).

```typescript
import { Curve, PlatformConfig } from '@raydium-io/raydium-sdk-v2'

// Fetch required data
const poolInfo = await raydium.launchpad.getRpcPoolInfo({ poolId })
const platformData = await raydium.connection.getAccountInfo(poolInfo.platformId)
const platformInfo = PlatformConfig.decode(platformData!.data)
const mintInfo = await raydium.token.getTokenInfo(mintA)
const slot = await raydium.connection.getSlot()

// Calculate buy quote
const buyQuote = Curve.buyExactIn({
  poolInfo,
  amountB: new BN('1000000000'),  // 1 SOL
  protocolFeeRate: poolInfo.configInfo.tradeFeeRate,
  platformFeeRate: platformInfo.feeRate,
  curveType: poolInfo.configInfo.curveType,
  shareFeeRate: new BN(0),
  creatorFeeRate: platformInfo.creatorFeeRate,
  transferFeeConfigA: mintInfo.extensions.feeConfig,  // For Token-2022
  slot,
})

console.log('Tokens out:', buyQuote.amountA.amount.toString())
console.log('Fees:', {
  protocol: buyQuote.splitFee.protocolFee.toString(),
  platform: buyQuote.splitFee.platformFee.toString(),
  creator: buyQuote.splitFee.creatorFee.toString(),
  share: buyQuote.splitFee.shareFee.toString(),
})

// Calculate sell quote
const sellQuote = Curve.sellExactIn({
  poolInfo,
  amountA: new BN('500000000000'),  // Tokens to sell
  protocolFeeRate: poolInfo.configInfo.tradeFeeRate,
  platformFeeRate: platformInfo.feeRate,
  curveType: poolInfo.configInfo.curveType,
  shareFeeRate: new BN(0),
  creatorFeeRate: platformInfo.creatorFeeRate,
  transferFeeConfigA: mintInfo.extensions.feeConfig,
  slot,
})

console.log('Quote tokens out:', sellQuote.amountB.toString())
```

### Métodos de cotización disponibles

| Método                 | Descripción                                                                             |
| ---------------------- | --------------------------------------------------------------------------------------- |
| `Curve.buyExactIn()`   | Calcula los tokens recibidos para una entrada dada de token de cotización               |
| `Curve.buyExactOut()`  | Calcula los tokens de cotización necesarios para una salida específica de token         |
| `Curve.sellExactIn()`  | Calcula los tokens de cotización recibidos para una entrada dada de token               |
| `Curve.sellExactOut()` | Calcula los tokens necesarios para recibir una salida específica de token de cotización |

## Comisiones por referidos

Los integradores pueden ganar comisiones por referidos pasando `shareFeeRate` y `shareFeeReceiver` parámetros.

```typescript
const { execute } = await raydium.launchpad.buyToken({
  // ... other params ...

  // Referral configuration
  shareFeeRate: new BN(5000),  // 0.5% referral fee
  shareFeeReceiver: new PublicKey('referrer-wallet'),
})
```

> **Nota:** `shareFeeRate` no puede exceder `maxShareFeeRate` de la configuración global. Las comisiones por referidos se pagan en el token de cotización (por ejemplo, SOL) y se transfieren directamente a la `shareFeeReceiver` wallet.

## Comprobando el estado del pool

Antes de tradear, verifica que el pool siga en estado de trading:

```typescript
const poolInfo = await raydium.launchpad.getRpcPoolInfo({ poolId })

if (poolInfo.status === 0) {
  console.log('Pool is active - trading enabled')
} else if (poolInfo.status === 1) {
  console.log('Pool is migrating - trading disabled')
} else if (poolInfo.status === 2) {
  console.log('Pool has migrated - trade on Raydium AMM instead')
}

// Check progress toward migration
const progress = poolInfo.realB.mul(new BN(100)).div(poolInfo.totalFundRaisingB)
console.log(`Fundraising progress: ${progress.toString()}%`)
```
