Lendasat LogoLendasat Docs
Create Swaps

BTC → EVM

Create a swap from Bitcoin (via Arkade, Lightning, or On-chain) to stablecoins on Polygon or Ethereum.

Overview

BTC to EVM swaps allow you to convert Bitcoin to stablecoins like USDC or USDT. The process:

  1. Create swap - Request a swap and get payment details
  2. Send BTC - Pay via Lightning invoice, Arkade VHTLC, or on-chain to a Taproot HTLC
  3. Claim stablecoins - Receive tokens on the EVM chain (gasless via Gelato)

Create Swap

Lightning → EVM

const result = await client.createLightningToEvmSwap({
  targetAddress: "0xYourPolygonAddress",
  targetToken: "usdc_pol",
  targetChain: "polygon",
  targetAmount: 50, // Receive exactly 50 USDC
});

console.log("Pay invoice:", result.response.ln_invoice);
console.log("Swap ID:", result.response.id);

Arkade → EVM

const result = await client.createArkadeToEvmSwap({
  targetAddress: "0xYourPolygonAddress",
  targetToken: "usdc_pol",
  targetChain: "polygon",
  sourceAmount: 100000,
});

console.log("Fund VHTLC:", result.response.htlc_address_arkade);
console.log("Swap ID:", result.response.id);

Complete Flow: Lightning → EVM

End-to-end example for Lightning to Polygon/Ethereum swap:

// 1. Create swap
const result = await client.createLightningToEvmSwap({
  targetAddress: "0xYourPolygonAddress",
  targetToken: "usdc_pol",
  targetChain: "polygon",
  sourceAmount: 100000,
});

console.log("Pay invoice:", result.response.ln_invoice);

// 2. Poll for status
let swap = await client.getSwap(result.response.id);
while (swap.status !== "serverfunded" && swap.status !== "clientredeemed") {
  await new Promise((r) => setTimeout(r, 3000));
  swap = await client.getSwap(result.response.id);
  console.log("Status:", swap.status);
}

// 3. Claim (gasless on Polygon)
if (swap.status === "serverfunded") {
  const claim = await client.claim(result.response.id);
  console.log("Claim result:", claim.success, claim.message);
}

By Target Amount (Receive Exact USDC)

Specify how much stablecoin you want to receive:

const result = await client.createLightningToEvmSwap({
  targetAddress: "0xYourPolygonAddress",
  targetToken: "usdc_pol",
  targetChain: "polygon",
  targetAmount: 50, // Receive exactly 50 USDC
});

console.log("Pay invoice:", result.response.ln_invoice);
console.log("Swap ID:", result.response.id);

By Source Amount (Send Exact BTC)

Specify how much BTC you want to send:

const result = await client.createLightningToEvmSwap({
  targetAddress: "0xYourPolygonAddress",
  targetToken: "usdc_pol",
  targetChain: "polygon",
  sourceAmount: 100000, // Send exactly 100,000 sats
});

console.log("Pay invoice:", result.response.ln_invoice);
console.log("You will receive:", result.response.target_amount, "USDC");

Swap Request Parameters

ParameterTypeRequiredDescription
targetAddressstringYesEVM address to receive stablecoins
targetAmountnumber*Amount of stablecoins to receive (e.g., 100)
sourceAmountbigint*Amount of sats to send (e.g., 100000n)
targetTokenstringYesToken ID (usdc_pol, usdt0_pol, usdc_eth, usdt_eth)
targetChainstringYesTarget chain (polygon, ethereum)
referralCodestringNoOptional referral code

Specify either targetAmount OR sourceAmount, not both. Use targetAmount to receive an exact stablecoin amount, or sourceAmount to send an exact BTC amount.


Swap Response

FieldTypeDescription
idstringUnique swap ID
sourceAmountnumberBTC amount in sats
targetAmountnumberStablecoin amount
targetAddressstringEVM address
vhtlcAddressstringArkade VHTLC address (Arkade swaps)
lnInvoicestringLightning invoice (Lightning swaps)
htlcAddressstringTaproot HTLC address (On-chain swaps)
exchangeRatenumberApplied exchange rate
statusstringCurrent swap status
createdAtstringCreation timestamp
expiresAtstringExpiration timestamp

Important Notes

Claim Within Timelock: After paying BTC, you must claim your stablecoins before the HTLC timelock expires (typically 10 minutes). The SDK handles this automatically when you call claim().

  1. Gasless on Polygon - Claiming is handled via Gelato Relay, no gas fees required
  2. Wallet needed on Ethereum - Ethereum claims require WalletConnect and user pays gas
  3. Payment timeout - Lightning invoices expire after ~10 minutes if unpaid
  4. Quote validity - Exchange rates are locked when the swap is created

Next Steps

After creating a swap:

  1. Pay the BTC - Send to VHTLC (Arkade), pay invoice (Lightning), or send to Taproot HTLC (On-chain)
  2. Monitor status - Check swap status using Get Swap by ID
  3. Claim stablecoins - Use Claim via Gelato for gasless claiming