# BlumeSwap Trading Skill

BlumeSwap is a Uniswap V2 AMM on XRPL EVM. Swap any ERC20 token pair, provide liquidity to earn 0.25% of swap fees, and query pool state. Live on mainnet and testnet.

**Important:** These docs are for programmatic agents using `cast`, `curl`, and `viem`. The web frontend at swap.blumefi.com requires a browser wallet (MetaMask, etc.).

## Contract Addresses

### Mainnet (Chain ID: 1440000)

| Contract | Address |
|----------|---------|
| Factory | `0x0F0F367e1C407C28821899E9bd2CB63D6086a945` |
| Router | `0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C` |
| WXRP | `0x7C21a90E3eCD3215d16c3BBe76a491f8f792d4Bf` |

### Testnet (Chain ID: 1449000)

| Contract | Address |
|----------|---------|
| Factory | `0xa67Dfa5C47Bec4bBbb06794B933705ADb9E82459` |
| Router | `0xC17E3517131E7444361fEA2083F3309B33a7320A` |
| WXRP | `0x664950b1F3E2FAF98286571381f5f4c230ffA9c5` |

**Testnet faucet:** `curl -X POST https://api.blumefi.com/faucet/drip -H "Content-Type: application/json" -d '{"address":"YOUR_ADDRESS"}'` — 25 XRP, 1hr cooldown.

## Swap Tokens

### Swap XRP for Tokens

```bash
# Mainnet: Swap 1 XRP for tokens
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "swapExactETHForTokens(uint256,address[],address,uint256)" \
  0 "[0x7C21a90E3eCD3215d16c3BBe76a491f8f792d4Bf,TOKEN_ADDRESS]" \
  YOUR_ADDRESS 99999999999 \
  --value 1ether \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000

# Testnet: Same but different addresses
cast send 0xC17E3517131E7444361fEA2083F3309B33a7320A \
  "swapExactETHForTokens(uint256,address[],address,uint256)" \
  0 "[0x664950b1F3E2FAF98286571381f5f4c230ffA9c5,TOKEN_ADDRESS]" \
  YOUR_ADDRESS 99999999999 \
  --value 1ether \
  --rpc-url https://rpc.testnet.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

### Swap Tokens for XRP

```bash
# Step 1: Approve token for Router
cast send TOKEN_ADDRESS \
  "approve(address,uint256)" ROUTER_ADDRESS \
  115792089237316195423570985008687907853269984665640564039457584007913129639935 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 500000

# Step 2: Swap tokens for XRP
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "swapExactTokensForETH(uint256,uint256,address[],address,uint256)" \
  AMOUNT_IN 0 "[TOKEN_ADDRESS,0x7C21a90E3eCD3215d16c3BBe76a491f8f792d4Bf]" \
  YOUR_ADDRESS 99999999999 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

### Swap Token to Token

```bash
# Approve first, then:
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)" \
  AMOUNT_IN 0 "[TOKEN_A,TOKEN_B]" \
  YOUR_ADDRESS 99999999999 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

**Note:** Multi-hop routes go through WXRP: `[TOKEN_A, WXRP, TOKEN_B]`.

## Add Liquidity

### CLI (Recommended)

```bash
# Add liquidity with 10 XRP (auto-calculates token amount from pool ratio)
npx blumefi swap add-liquidity 0xTOKEN_ADDRESS 10

# Add liquidity on mainnet with 5% slippage
npx blumefi swap add-liquidity 0xTOKEN_ADDRESS 10 --mainnet --slippage 5
```

Handles ERC20 approval, reserve ratio calculation, and slippage protection automatically. Default slippage: 2%.

### Direct Contract Calls

```bash
# Approve the token first, then:
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "addLiquidityETH(address,uint256,uint256,uint256,address,uint256)" \
  TOKEN_ADDRESS TOKEN_AMOUNT 0 0 YOUR_ADDRESS 99999999999 \
  --value XRP_AMOUNT_IN_WEI \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

### Add Liquidity (Two Tokens)

```bash
# Approve both tokens first, then:
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "addLiquidity(address,address,uint256,uint256,uint256,uint256,address,uint256)" \
  TOKEN_A TOKEN_B AMOUNT_A AMOUNT_B 0 0 YOUR_ADDRESS 99999999999 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

## Remove Liquidity

### CLI (Recommended)

```bash
# Remove all liquidity from a token/XRP pool
npx blumefi swap remove-liquidity 0xTOKEN_ADDRESS all

# Remove a specific amount of LP tokens
npx blumefi swap remove-liquidity 0xTOKEN_ADDRESS 5.0

# Remove liquidity on mainnet with 5% slippage
npx blumefi swap remove-liquidity 0xTOKEN_ADDRESS all --mainnet --slippage 5
```

Handles LP token approval, reserve estimation, and slippage protection automatically. Default slippage: 2%.

### Direct Contract Calls

```bash
# Step 1: Approve LP token for Router
cast send PAIR_ADDRESS \
  "approve(address,uint256)" 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  115792089237316195423570985008687907853269984665640564039457584007913129639935 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 500000

# Step 2: Remove liquidity (XRP pair)
cast send 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "removeLiquidityETH(address,uint256,uint256,uint256,address,uint256)" \
  TOKEN_ADDRESS LP_AMOUNT 0 0 YOUR_ADDRESS 99999999999 \
  --rpc-url https://rpc.xrplevm.org \
  --private-key $WALLET_PRIVATE_KEY \
  --gas-limit 1000000
```

## Read-Only Queries

```bash
# Get expected output for a swap (mainnet)
cast call 0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C \
  "getAmountsOut(uint256,address[])(uint256[])" \
  1000000000000000000 "[0x7C21a90E3eCD3215d16c3BBe76a491f8f792d4Bf,TOKEN_ADDRESS]" \
  --rpc-url https://rpc.xrplevm.org

# Get pair address
cast call 0x0F0F367e1C407C28821899E9bd2CB63D6086a945 \
  "getPair(address,address)(address)" \
  TOKEN_A TOKEN_B \
  --rpc-url https://rpc.xrplevm.org

# Get reserves for a pair
cast call PAIR_ADDRESS \
  "getReserves()(uint112,uint112,uint32)" \
  --rpc-url https://rpc.xrplevm.org

# Count all pairs
cast call 0x0F0F367e1C407C28821899E9bd2CB63D6086a945 \
  "allPairsLength()(uint256)" \
  --rpc-url https://rpc.xrplevm.org

# Get pair by index
cast call 0x0F0F367e1C407C28821899E9bd2CB63D6086a945 \
  "allPairs(uint256)(address)" INDEX \
  --rpc-url https://rpc.xrplevm.org
```

## Value Formats

| Type | Decimals | Example |
|------|----------|---------|
| XRP / WXRP | 18 | `1000000000000000000` = 1 XRP |
| Most ERC20 tokens | 18 | Check with `decimals()` call |
| Deadline | Unix timestamp | Use `99999999999` for no deadline |

## Fee Structure

- **Swap fee**: 0.3% per trade
- **LP share**: 0.25% goes to liquidity providers
- **Protocol**: 0.05% to protocol (when `feeTo` is set)

## XRPL EVM Tips

- **Always set explicit gas**: `--gas-limit 1000000` for swaps, `--gas-limit 500000` for approvals
- **Deadline**: Use a far-future timestamp like `99999999999` to avoid deadline reverts
- **Slippage**: Set `amountOutMin` to 0 for testing, calculate properly for production
- **WXRP wrapping**: Router handles XRP↔WXRP automatically via `*ETH` methods

## Query via API

The Blume API indexes all BlumeSwap data and supports `?chain=mainnet|testnet` filtering.

```bash
# List all pools (testnet)
curl https://api.blumefi.com/dex/pools?chain=testnet

# List all pools (mainnet)
curl https://api.blumefi.com/dex/pools?chain=mainnet

# Pool detail (by pair address)
curl https://api.blumefi.com/dex/pools/PAIR_ADDRESS

# Pool events (swaps, mints, burns)
curl "https://api.blumefi.com/dex/pools/PAIR_ADDRESS/events?limit=20"

# All indexed tokens
curl https://api.blumefi.com/dex/tokens?chain=testnet
```

Omit `?chain=` to get data from all networks.

## Ecosystem Links

- [Ecosystem Hub](https://blumefi.com/skill.md) — All Blume apps
- [Pad](https://pad.blumefi.com/skill.md) — Launch tokens that trade on BlumeSwap after graduation
- [Mainnet Explorer](https://explorer.xrplevm.org)
- [Testnet Explorer](https://explorer.testnet.xrplevm.org)
