- TeleSwap SDK Integration
- Initialize SDK
- Estimate output amount
- Create unsigned transaction
- Create and sign transaction
- Get transaction status
- Get account history
- Data models details
- Examples
TeleSwap enables secure and seamless bridging of Bitcoin assets (BTC, BRC-20s, and RUNEs) across blockchains. The SDK provides core functionalities for bridging Bitcoin assets between Bitcoin <> EVM networks.
The SDK provides four main functionalities:
- wrapAndSwap: Convert BTC to ERC-20
- swapAndUnwrap: Convert ERC-20 to BTC
In TeleSwap, we define two types of networks:
-
Source Network: It refers to Bitcoin.
-
Target Network: It refers to EVM networks (and soon TON). There are two types of target networks:
- Base networks: These networks are directly connected to Bitcoin.
- Cross-chain networks: These networks rely on a base network as an intermediary.
You can swap BTC ⇄ ERC-20 tokens on the following networks:
- Polygon: USDT, USDC, USDC.e, WBTC, WETH, MATIC, WMATIC, TELEBTC
- BNB: USDT, USDC, ETH, BTCB, BNB, WBNB, TELEBTC, TST(Test)
Cross-chain networks use a base network as an intermediary.
- Ethereum: USDT, USDC, ETH, WETH, WBTC
- Optimism: USDT, USDC, ETH, WETH, WBTC
- Arbitrum: USDT, USDC, ETH, WETH, WBTC
- Base: USDC, ETH, WETH
First, create an instance of the SDK class.
- Optional: Set the default network (e.g. Polygon)
let sdk = new TeleswapSDK()
// set default network (optional)
sdk.setDefaultNetwork({
networkName: "polygon",
})
The default Bitcoin connections are MempoolSpace and TeleportDAO for retrieving UTXOs and Bitcoin fee rates.
To interact with EVM networks, add network connection information to the SDK.
// Initialize all networks with TeleportDAO RPC
await sdk.initNetworksConnection()
// Use this method to set custom RPCs for specific networks while keeping the default TeleportDAO RPCs for others.
await sdk.initNetworksConnection([
{
networkName: "ethereum",
web3: {
url: "https://example.com",
},
},
])
// Add your custom RPC
sdk.addNetwork({
networkName: "bsc",
web3: {
url: "https://example.com",
},
})
To sign transactions on Bitcoin or EVM networks using a mnemonic, initialize the account with the mnemonic.
- If you only use EVM or Bitcoin, you can skip initialization for the other.
// Init Bitcoin account
let mnemonic = "..."
let bitcoinAddress = sdk.initBitcoinAccountUsingMnemonic(mnemonic)
// Init EVM account
let evmAddress = sdk.initEvmAccountUsingMnemonic(mnemonic)
Get the addresses of Bitcoin and EVM accounts using the following methods (need to initialize SDK first)
let bitcoinAddress = sdk.bitcoinAddress
let bitcoinAddressType = sdk.bitcoinAddressType
let targetNetworkAddress = sdk.evmAddress
To assign third-party ID requests and receive fees accordingly, initialize the SDK with your thirdPartyId.
Note: Please contact us on Discord to obtain your Third Party ID.
const thirdPartyId = 10
await sdk.setThirdPartyId(thirdPartyId)
let amountInBTC = 0.001
let networkName: = "optimism"
let outputTokenAddress = "token contract address" // leave it empty (undefined) for native token
let estimateResponse = await sdk.wrapAndSwapEstimate(
amountInBTC,
networkName,
outputTokenAddress,
)
-
estimateResponse.inputAmountBTC
: BTC amount on bitcoin network -
estimateResponse.outputAmount
: Output amount on EVM network -
estimateResponse.teleswapFee
: Details of the TeleSwap fee
SEE EXAMPLE RESPONSE
{
"minInputAmountBTC": "0.000015015",
"inputAmountBTC": "0.001",
"outputAmount": "96628248",
"teleswapFee": {
"networkFeeBTC": "0.00001000",
"protocolFeeBTC": "0.00000000",
"lockerFeeBTC": "0.00000100",
"thirdPartyFeeBTC": "0.00000000",
"totalFeeBTC": "0.00001100"
},
"internalExchange": {
"path": "BTC-TELEBTC(polygon)->0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359(polygon)",
"inputAmount": "98900",
"outputAmount": "96647357"
},
// internalBridge can be undefined
"internalBridge": {
"path": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359(polygon)->0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913(base)",
"fee": "19109"
}
}
let networkName: = "optimism"
let exchangeInfo = {
inputToken: "Token Contract Address",
inputAmount: BigNumber("50")
.multipliedBy(10 ** 18) // decimal = 18
.toFixed(0), // for example (50 WMatic)
}
let estimateResponse = await sdk.swapAndUnwrapEstimate(
exchangeInfo,
networkName,
)
-
estimateResponse.teleswapFee
: Details of the TeleSwap fee -
estimateResponse.inputAmount
: Input amount on EVM network -
estimateResponse.outputAmountBTC
: BTC amount on bitcoin network
SEE EXAMPLE RESPONSE
{
"inputAmount": "100000000",
"outputAmountBTC": "0.00101470",
"teleswapFee": {
"networkFeeBTC": "0.00000600",
"protocolFeeBTC": "0.00000000",
"lockerFeeBTC": "0.00000102",
"thirdPartyFeeBTC": "0.00000000",
"totalFeeBTC": "0.00000702"
},
"internalExchange": {
"path": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359(polygon)->TELEBTC(polygon)",
"inputAmount": "100000000",
"outputAmount": "102172"
},
// internal bridge can be undefined
"internalBridge": {
"path": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913(base)->0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359(polygon)",
"fee": "11048"
},
"minInputAmountBTC": "0.000159165"
}
Use the methods below to create unsigned transactions or retrieve the inputs needed for direct contract calls.
This function enables swapping BTC on Bitcoin for tokens on EVM networks.
// You need to provide the relevant exchange information
let amountInBTC = 0.001
let evmAddress = "0x..."
let networkName = "ethereum"
let exchangeTokenAddress = "0x..." // leave it empty (undefined) for native token
// You need to provide Bitcoin account details to create an unsigned transaction
const signerInfo: {
addressType: "p2wpkh" | "p2pkh" | "p2sh-p2wpkh"
publicKey: string
address: string
}
const unsignedResponse = await sdk.wrapAndSwapUnsigned(
evmAddress,
amountInBTC,
signerInfo,
network,
exchangeTokenAddress,
)
This function enables swapping EVM tokens to receive BTC in return.
Note: You can obtain the inputs for the swapAndUnwrap function and call the contract directly:
- To interact with the contract directly, you must grant approval to the contract for an amount equal to the input value.
- If your network is a base network, call the BurnRouter contract.
- If your network is a cross-chain network, call the EthConnector contract.
let recipientBitcoinAddress = "..."
let exchangeInfo = {
inputToken: "Token Contract Address",
inputAmount: BigNumber("50")
.multipliedBy(10 ** 18) // decimal = 18
.toFixed(0), // for example (50 WMatic)
}
let network = "optimism"
// If the received amount is less than minimumExpectedBTCAmount, the transaction will fail
const minimumExpectedBTCAmount = "0"
// If your account is not initialized, you can obtain the function inputs and interact with the contract directly
const swapAndUnwrapInputs = await sdk.swapAndUnwrapInputs(
exchangeInfo,
btcAddress,
network,
minimumExpectedBTCAmount,
)
SEE EXAMPLE RESPONSE
{
"locker": {
"sourceAddress": "3CAQAw7m95axbY761Xq8d9DADhjNaX9b8o",
"targetAddress": "0x13ffEe453a15E627Cd2aCbb23A735ab57c7C298f",
"lockingScript": "0xa91472df0f82c4bcfe01a274bd521e5d4c66586b7a5b87"
},
"inputs": {
"params": [
"0x4e3e1807aa17aed8d1FC580dDa552079d9427ece",
[
"5000000000000000",
"0"
],
true,
[
"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
"0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
"0x3BF668Fe1ec79a84cA8481CEAD5dbb30d61cC685"
],
1730308950,
"0x7858574ca53954113221037a0f6a667ffa03babc",
3,
"0xa91472df0f82c4bcfe01a274bd521e5d4c66586b7a5b87",
0
],
"value": "0"
}
}
import { ABI } from "@teleportdao/contracts-helper"
import { teleswap } from "@teleportdao/configs"
// BurnRouter ABI
const ccBurnABI = ABI.CCBurnRouterABI
// EthConnector ABI
const connectorABI = ABI.TeleswapEthConnectorABI
// BurnRouter Contract Addresses (for Polygon and BSC)
const polygonCCBurnAddress = teleswap.contracts.polygon.mainnet.ccBurnAddress
const bscCCBurnAddress = teleswap.contracts.bsc.mainnet.ccBurnAddress
// Connector Contract Address (for Ethereum, Arbitrum, Optimism, and Base)
const ethereumConnectorAddress = teleswap.connectors.ethereum.mainnet.connectorAddress
const arbitrumConnectorAddress = teleswap.connectors.arbitrum.mainnet.connectorAddress
const optimismConnectorAddress = teleswap.connectors.optimism.mainnet.connectorAddress
const baseConnectorAddress = teleswap.connectors.base.mainnet.connectorAddress
For the following functions, you must first initialize the SDK with a mnemonic.
This function enables swapping BTC on Bitcoin for tokens on EVM networks.
// You need to provide the relevant exchange information
// The exchange token address is the address of the token on the target chain
let amountInBTC = 0.001
let evmAddress = "0x..."
let networkName = "ethereum"
let exchangeTokenAddress = "0x..." // leave it empty (undefined) for native token
const response = await sdk.wrapAndSwap(evmAddress, amountInBTC, networkName, exchangeTokenAddress)
This function enables swapping EVM tokens to receive BTC in return.
let recipientBitcoinAddress = "..."
let exchangeInfo = {
inputToken: "Token Contract Address",
inputAmount: BigNumber("50")
.multipliedBy(10 ** 18) // decimal = 18
.toFixed(0), // for example (50 WMatic)
}
let network = "optimism"
const minimumExpectedBTCAmount = "0"
let response = await sdk.swapAndUnwrap(
exchangeInfo,
recipientBitcoinAddress,
network,
minimumExpectedBTCAmount,
)
You can use your EVM or Bitcoin TXID to retrieve the status of your transaction.
- ⚠ Note: There may be a short delay after sending the transaction before this method becomes available.
- ⚠ Note: When the state is Pending, the sourceTransaction might be null, and the fee details might be set to 0. This indicates that the transaction is still being processed, and certain information may not yet be available.
const txId = "..."
const response = await sdk.teleportdao.getRequestStatusByTxId(txId)
-
response.state
: it can be Pending or Done.
SEE EXAMPLE RESPONSE
{
"id": "5277",
"sourceTransactionId": 12300,
"targetEventId": "592286",
"fromNetworkId": "2",
"fromAddress": "bc1qpeq8fe6e8unzagwq9mhd4f6end0tzj9ylusckm",
"inputTokenContractId": "106",
"inputTokenAmount": "3400000",
"inputTokenAmountUSD": "3343.7837",
"toNetworkId": "5",
"outputTokenContractId": "13",
"outputTokenAmount": "3391434",
"outputTokenAmountUSD": "3339.4565",
"toAddress": "0x2De41A894aE9d7Ad8899E55911082BDD8dE0Af25",
"lockerId": "1",
"networkFee": "1000",
"lockerFee": "3400",
"protocolFee": "0",
"thirdPartyFee": "0",
"bridgeFee": "4120",
"totalFee": "4400",
"crossChainId": "517",
"thirdPartyId": 0,
"tokenType": "BTC",
"type": "WrapAndSwap",
"status": "Submitted",
"createdAt": "2025-02-11T06:33:33.247Z",
"updatedAt": "2025-02-11T06:45:17.127Z",
"fromNetwork": {
"id": "2",
"name": "bitcoin",
"title": "Bitcoin",
"lastBlock": "883301",
"chainId": 0,
"status": "Active",
"details": null
},
"toNetwork": {
"id": "5",
"name": "ethereum",
"title": "Ethereum",
"lastBlock": "0",
"chainId": 1,
"status": "Active",
"details": {}
},
"sourceTransaction": {
"txId": "058de9c7396390ae2ceecca1ab772b877e1355a12dab7a550887ab085fc3a4f2"
},
"targetEvent": {
"targetTransaction": {
"txId": "0xbbccc2c477fbecc5e828943d5d81a47f14b17c0a9fbaac091d4ebb7de8e3bccf"
}
},
"inputToken": {
"id": "106",
"contractAddress": "0x3BF668Fe1ec79a84cA8481CEAD5dbb30d61cC685",
"name": "teleBTC",
"symbol": "TELEBTC",
"type": "ERC20",
"coinId": "1",
"networkId": "1",
"decimal": 8,
"status": "Active",
"details": {},
"coin": {
"id": "1",
"slug": "BTC",
"title": "Bitcoin",
"priceUSD": "98022.07",
"type": "Coin",
"details": {}
}
},
"outputToken": {
"id": "13",
"contractAddress": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
"name": "(PoS) Wrapped BTC",
"symbol": "WBTC",
"type": "ERC20",
"coinId": "1",
"networkId": "1",
"decimal": 8,
"status": "Active",
"details": {},
"coin": {
"id": "1",
"slug": "BTC",
"title": "Bitcoin",
"priceUSD": "98022.07",
"type": "Coin",
"details": {}
}
},
"state": "Done"
}
You can use your EVM or Bitcoin address to retrieve the corresponding transactions.
const bitcoinAndEVMAddresses = ["0x...", "bc1..."]
const optionalConfig:
| {
createdAtAfter?: string
createdAtBefore?: string
tokenType?: "BTC" | "Rune" | "BRC20"
type?: "Wrap" | "Unwrap" | "WrapAndSwap" | "SwapAndUnwrap"
tokenAddress?: string
network?: SupportedNetworkAll
filter?: "all" | "done" | "pending"
limit?: number
offset?: number
order?: "asc" | "desc"
}
| undefined = {}
const response = await sdk.teleportdao.getRequests(bitcoinAndEVMAddresses, optionalConfig)
// or you can get all
const allRequests = await sdk.teleportdao.getAllRequests(optionalConfig)
⚠ Note: The requests with a Waiting status are not included in this API. You can use the function below to retrieve them for an EVM address
const waitingRequests = await sdk.teleportdao.getWaitingRequests(evmAddress)
This JSON represents a SwapAndUnwrap transaction involving Tether USD (USDT) being swapped for Bitcoin (BTC), across the Optimism and Bitcoin networks.
-
fromNetwork
(Optimism):-
id
:23
-
name
:"optimism"
-
title
:"Optimism"
-
chainId
:10
-
status
:"Active"
-
-
toNetwork
(Bitcoin):-
id
:2
-
name
:"bitcoin"
-
title
:"Bitcoin"
-
chainId
:0
-
status
:"Active"
-
-
sourceTransaction.txId
:1c7147b749bc538812ed723158c92ecac59a5b0d95653fb52677f7586f088037
- This is the transaction ID on the Bitcoin network.
-
targetEvent.targetTransaction.txId
:0x654ad7aeb7353a41dd0098a29d237e3f75e7ce7db31a81379a94bbb88ad94e77
- This is the corresponding transaction ID on the EVM(Optimism) network.
-
fromAddress
:0xc72275e227404FcB7AcA3027eB0889578866902E
- The sender's address (on Optimism).
-
toAddress
:bc1qr92h65ezequh2zw5g79tj3nqqza6s4ytdgms3w
- The recipient's address (on Bitcoin).
-
inputTokenAmount
:535915000
(in USDT with decimal of inputToken.decimal). -
inputTokenAmountUSD
:$535.92
(approximate USD value of input tokens). -
outputTokenAmount
:559437
(in teleBTC with decimal of outputToken.decimal). -
outputTokenAmountUSD
:$533.1605
(approximate USD value of output tokens).
-
id
:93
-
contractAddress
:0x94b008aA00579c1307B0EF2c499aD98a8ce58e58
-
name
:"Tether USD"
-
symbol
:"USDT"
-
type
:"ERC20"
-
networkId
:23
(Optimism network) -
decimal
:6
-
status
:"Active"
-
coin.priceUSD
:$1
- The price of USDT in USD (as a stablecoin).
-
id
:106
-
contractAddress
:0x3BF668Fe1ec79a84cA8481CEAD5dbb30d61cC685
-
name
:"teleBTC"
-
symbol
:"TELEBTC"
-
type
:"ERC20"
-
networkId
:1
(Ethereum network) -
decimal
:8
-
status
:"Active"
-
coin.priceUSD
:$97723.43
- The price of Bitcoin (BTC) in USD.
-
networkFee
:600
(gas or transaction fee). -
lockerFee
:840
(locker fee). -
protocolFee
:280
(protocol fee, if any). -
thirdPartyFee
:0
(third-party fee, if any). -
bridgeFee
:0
(cross-chain bridging fee). -
totalFee
:1720
(sum of all fees).
-
thirdPartyId
:"0"
. -
type
:"SwapAndUnwrap"
(indicates a swap and unwrap transaction between Bitcoin and Optimism). -
status
:"Submitted"
(current transaction state). -
state
:"Done"
(the final state of the transaction after completion). -
createdAt
:2025-02-03T10:43:04.281Z
(timestamp of creation. use this for request time). -
updatedAt
:2025-02-03T11:04:38.200Z
(timestamp of last update). -
Note: If either the input or output network is Bitcoin, the token involved is teleBTC, but the actual transfer of BTC happens on the Bitcoin network.
The state represents the general lifecycle of a transaction request. It can have the following values:
- Pending: The transaction request has been initiated and is currently being processed.
- Done: The transaction process has been completed.
The status provides more specific information about the transaction's state in the network or protocol. Possible values include:
- NotProcessed: The transaction has not been processed yet.
- Pending: The transaction has been sent and is in the mempool, awaiting confirmation.
- Confirmed: The transaction has received at least one confirmation from the network.
- Submitted: Proof of the transaction has been submitted to the protocol.
- Failed: The transaction has failed.
- ExchangeFailed: The transaction failed specifically during the exchange process and user received TELEBTC.
- State reflects whether the transaction request is still being processed or has finished.
- Status provides detailed insight into the transaction's progression in the network or protocol.
⚠ Note: When the state is Pending, the sourceTransaction (bitcoin transaction) might be null, and the fee details might be set to 0. This indicates that the transaction is still being processed, and certain information may not yet be available.
For more information, please check the example.