diff --git a/api-reference/deposit-actions/bitcoin.mdx b/api-reference/deposit-actions/bitcoin.mdx
new file mode 100644
index 0000000..94c4369
--- /dev/null
+++ b/api-reference/deposit-actions/bitcoin.mdx
@@ -0,0 +1,291 @@
+---
+title: 'Bitcoin'
+description: 'Execute deposit transactions on Bitcoin mainnet and testnet using PSBT construction.'
+---
+
+## Overview
+
+Bitcoin deposits use a UTXO-based model. The `call_data` from the transfer action is a **numeric memo** that must be embedded in the transaction as an `OP_RETURN` output. This memo is how Layerswap identifies and matches your deposit.
+
+**Prerequisites:**
+- [bitcoinjs-lib](https://github.com/bitcoinjs/bitcoinjs-lib) for PSBT construction
+- [@bitcoinerlab/secp256k1](https://github.com/bitcoinerlab/secp256k1) for elliptic curve operations
+- Access to a Bitcoin node or the [Mempool.space API](https://mempool.space/docs/api) for UTXO data and fee estimates
+
+## call_data Format
+
+For Bitcoin, `call_data` is a **numeric string** representing a memo identifier. Before embedding it into the transaction, convert it to a hex string:
+
+```javascript
+const hexMemo = Number(callData).toString(16);
+```
+
+This hex memo is embedded as an `OP_RETURN` output in the transaction.
+
+## Transaction Construction
+
+
+
+ Retrieve unspent transaction outputs for the sender's address. You can use the Mempool.space API or your own Bitcoin node.
+
+
+ For each UTXO, fetch the full raw transaction hex. This is needed to populate the `witnessUtxo` field in the PSBT inputs.
+
+
+ Select enough UTXOs to cover the deposit amount plus estimated fees.
+
+
+ Create a PSBT with:
+ - **Inputs**: Selected UTXOs with witness data
+ - **Output 1**: Payment to `to_address` for the deposit `amount`
+ - **Output 2**: `OP_RETURN` with the hex-encoded memo
+ - **Output 3** (if needed): Change back to the sender's address
+
+
+ Fetch the recommended fee rate from Mempool.space and calculate the transaction fee based on input/output count. Re-select UTXOs if the initial selection doesn't cover the fee.
+
+
+ Sign the PSBT with your private key and broadcast the raw transaction.
+
+
+
+## Full Example
+
+```typescript
+import {
+ Psbt,
+ Transaction,
+ networks,
+ opcodes,
+ script,
+ initEccLib,
+ payments,
+} from "bitcoinjs-lib";
+import * as ecc from "@bitcoinerlab/secp256k1";
+import ECPairFactory from "ecpair";
+import axios from "axios";
+
+initEccLib(ecc);
+const ECPair = ECPairFactory(ecc);
+
+interface Utxo {
+ txid: string;
+ vout: number;
+ value: number;
+ status: { confirmed: boolean };
+}
+
+const MEMPOOL_BASE = {
+ mainnet: "https://mempool.space",
+ testnet: "https://mempool.space/testnet",
+};
+
+async function fetchUtxos(
+ address: string,
+ version: "mainnet" | "testnet"
+): Promise {
+ const base = MEMPOOL_BASE[version];
+ const { data } = await axios.get(
+ `${base}/api/address/${address}/utxo`
+ );
+ return data;
+}
+
+async function fetchRawTx(
+ txid: string,
+ version: "mainnet" | "testnet"
+): Promise {
+ const base = MEMPOOL_BASE[version];
+ const { data } = await axios.get(`${base}/api/tx/${txid}/hex`);
+ return Transaction.fromHex(data);
+}
+
+async function fetchFeeRate(
+ version: "mainnet" | "testnet"
+): Promise {
+ const base = MEMPOOL_BASE[version];
+ const { data } = await axios.get(`${base}/api/v1/fees/recommended`);
+ return data.economyFee; // sats/vByte
+}
+
+function selectUtxos(
+ utxos: Utxo[],
+ target: bigint
+): { selected: Utxo[]; total: bigint } {
+ const sorted = utxos.slice().sort((a, b) => a.value - b.value);
+ let sum = 0n;
+ const selected: Utxo[] = [];
+ for (const u of sorted) {
+ selected.push(u);
+ sum += BigInt(u.value);
+ if (sum >= target) break;
+ }
+ if (sum < target) {
+ throw new Error(`Insufficient funds: need ${target} sats, have ${sum}`);
+ }
+ return { selected, total: sum };
+}
+
+function estimateTxFee(
+ numInputs: number,
+ numOutputs: number,
+ satsPerVbyte: number
+): bigint {
+ return BigInt((numInputs * 148 + numOutputs * 34 + 10) * satsPerVbyte);
+}
+
+async function executeBitcoinDeposit(
+ depositAction: any,
+ senderAddress: string,
+ senderWIF: string,
+ isTestnet = false
+) {
+ const { call_data, to_address, amount } = depositAction;
+ const version = isTestnet ? "testnet" : "mainnet";
+ const network = isTestnet ? networks.testnet : networks.bitcoin;
+ const amountSats = Math.floor(amount * 1e8);
+
+ // Convert numeric memo to hex for OP_RETURN
+ const hexMemo = Number(call_data).toString(16);
+ const memoBuffer = Buffer.from(hexMemo, "utf8");
+
+ if (memoBuffer.length > 80) {
+ throw new Error("Memo too long; max 80 bytes for OP_RETURN");
+ }
+
+ // Fetch UTXOs and fee rate
+ const utxos = await fetchUtxos(senderAddress, version);
+ const feeRate = await fetchFeeRate(version);
+
+ // Iteratively build PSBT to account for fees
+ let fee = 0n;
+ let psbt: Psbt;
+ let totalSelected: bigint;
+
+ do {
+ const target = BigInt(amountSats) + fee;
+ const { selected, total } = selectUtxos(utxos, target);
+ totalSelected = total;
+
+ psbt = new Psbt({ network });
+
+ // Add inputs
+ for (const utxo of selected) {
+ const rawTx = await fetchRawTx(utxo.txid, version);
+ const out = rawTx.outs[utxo.vout];
+ psbt.addInput({
+ hash: utxo.txid,
+ index: utxo.vout,
+ witnessUtxo: { script: out.script, value: out.value },
+ });
+ }
+
+ // Payment output
+ psbt.addOutput({
+ address: to_address,
+ value: BigInt(amountSats),
+ });
+
+ // OP_RETURN memo output
+ psbt.addOutput({
+ script: script.compile([opcodes.OP_RETURN, memoBuffer]),
+ value: 0n,
+ });
+
+ // Re-estimate fee
+ fee = estimateTxFee(
+ psbt.txInputs.length,
+ psbt.txOutputs.length + 1, // +1 for potential change output
+ feeRate
+ );
+ } while (totalSelected < BigInt(amountSats) + fee);
+
+ // Change output
+ const change = totalSelected - BigInt(amountSats) - fee;
+ if (change > 0n) {
+ psbt.addOutput({ address: senderAddress, value: change });
+ }
+
+ // Sign all inputs
+ const keyPair = ECPair.fromWIF(senderWIF, network);
+ const isTaproot =
+ senderAddress.startsWith("bc1p") || senderAddress.startsWith("tb1p");
+
+ for (let i = 0; i < psbt.inputCount; i++) {
+ if (isTaproot) {
+ psbt.signInput(i, keyPair, [Transaction.SIGHASH_DEFAULT]);
+ } else {
+ psbt.signInput(i, keyPair);
+ }
+ }
+
+ psbt.finalizeAllInputs();
+ const rawTxHex = psbt.extractTransaction().toHex();
+
+ // Broadcast via Mempool.space
+ const { data: txHash } = await axios.post(
+ `${MEMPOOL_BASE[version]}/api/tx`,
+ rawTxHex,
+ { headers: { "Content-Type": "text/plain" } }
+ );
+
+ return txHash;
+}
+```
+
+## Signing for Different Address Types
+
+Bitcoin has several address formats, each with different signing requirements:
+
+| Address Prefix | Type | Sighash |
+|---|---|---|
+| `1...` | Legacy (P2PKH) | `SIGHASH_ALL` (1) |
+| `3...` | Nested SegWit (P2SH-P2WPKH) | `SIGHASH_ALL` (1) |
+| `bc1q...` / `tb1q...` | Native SegWit (P2WPKH) | `SIGHASH_ALL` (1) |
+| `bc1p...` / `tb1p...` | Taproot (P2TR) | `SIGHASH_DEFAULT` (0) |
+
+
+ Taproot addresses require `SIGHASH_DEFAULT` (0) instead of `SIGHASH_ALL` (1). Using the wrong sighash type will produce an invalid signature.
+
+
+## Hardware / Browser Wallet Signing
+
+If you're using a wallet provider (e.g., Xverse, Unisat, Leather) instead of a raw private key, the flow changes at the signing step. Instead of signing locally, you pass the unsigned PSBT hex to the wallet's `signPsbt` method:
+
+```typescript
+const psbtHex = psbt.toHex();
+const isTaproot =
+ senderAddress.startsWith("bc1p") || senderAddress.startsWith("tb1p");
+
+const signedPsbtHex = await walletProvider.request({
+ method: "signPsbt",
+ params: {
+ psbt: psbtHex,
+ inputsToSign: [
+ {
+ address: senderAddress,
+ signingIndexes: Array.from({ length: psbt.inputCount }, (_, i) => i),
+ sigHash: isTaproot ? 0 : 1,
+ },
+ ],
+ finalize: false,
+ },
+});
+
+const signedPsbt = Psbt.fromHex(signedPsbtHex);
+signedPsbt.finalizeAllInputs();
+const rawTxHex = signedPsbt.extractTransaction().toHex();
+```
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/evm.mdx b/api-reference/deposit-actions/evm.mdx
new file mode 100644
index 0000000..467a096
--- /dev/null
+++ b/api-reference/deposit-actions/evm.mdx
@@ -0,0 +1,174 @@
+---
+title: 'EVM Chains'
+description: 'Execute deposit transactions on Ethereum, Arbitrum, Optimism, Base, Polygon, and other EVM-compatible networks.'
+---
+
+## Overview
+
+This guide covers all EVM-compatible networks supported by Layerswap, including Ethereum, Arbitrum, Optimism, Base, Polygon, Linea, zkSync Era, Scroll, and others.
+
+**Prerequisites:**
+- [viem](https://viem.sh/) (recommended) or [ethers.js](https://docs.ethers.org/)
+- A wallet client or signer with funds on the source network
+
+## call_data Format
+
+For EVM chains, `call_data` is a **hex-encoded string** (`0x...`) representing the transaction's `data` field. It always carries a Layerswap memo (a fixed prefix followed by a sequence number) that the backend uses to match the deposit:
+
+- **Native token transfers** (ETH, MATIC, etc.): `call_data` is the memo hex. `to_address` is the deposit address and `amount` / `amount_in_base_units` carry the value to send.
+- **ERC-20 token transfers**: `call_data` is the encoded `transfer(address,uint256)` function call with the memo hex appended. `to_address` is the **token contract**, and `amount` / `amount_in_base_units` are `0` — the actual transfer value is encoded inside `call_data`.
+
+In both cases, build the transaction with `to: to_address`, `value: amount`, and `data: call_data` and the wallet will route it correctly.
+
+## Transaction Construction
+
+
+
+ Extract `call_data`, `to_address`, `amount`, and `network.chain_id` from the transfer action.
+
+
+ Construct a transaction object with the transfer action fields mapped to standard EVM transaction parameters.
+
+
+ Call `eth_estimateGas` for a more accurate gas limit. If estimation fails, the transaction can still be sent without an explicit gas limit — the wallet or node will estimate it.
+
+
+ Sign and broadcast the transaction, then return the hash.
+
+
+
+## Full Example
+
+Pick the library that fits your stack. The `viem` and `ethers.js` tabs cover server-side or Node.js usage. The `wagmi` tab is for browser-side use with a connected wallet.
+
+
+```typescript viem
+import { createWalletClient, createPublicClient, http, parseEther } from "viem";
+import { privateKeyToAccount } from "viem/accounts";
+import { mainnet, arbitrum, optimism, base, polygon } from "viem/chains";
+
+const CHAIN_MAP = {
+ 1: mainnet,
+ 42161: arbitrum,
+ 10: optimism,
+ 8453: base,
+ 137: polygon,
+ // Add other EVM chains as needed
+};
+
+async function executeEvmDeposit(depositAction, privateKey) {
+ const { call_data, to_address, amount, network } = depositAction;
+ const chainId = Number(network.chain_id);
+ const chain = CHAIN_MAP[chainId];
+
+ if (!chain) {
+ throw new Error(`Unsupported chain ID: ${chainId}`);
+ }
+
+ const account = privateKeyToAccount(privateKey);
+
+ const walletClient = createWalletClient({
+ account,
+ chain,
+ transport: http(network.node_url),
+ });
+
+ const publicClient = createPublicClient({
+ chain,
+ transport: http(network.node_url),
+ });
+
+ // Estimate gas
+ let gas;
+ try {
+ gas = await publicClient.estimateGas({
+ account: account.address,
+ to: to_address,
+ value: parseEther(amount.toString()),
+ data: call_data,
+ });
+ } catch (error) {
+ console.warn("Gas estimation failed, proceeding without explicit gas limit");
+ }
+
+ // Send transaction
+ const hash = await walletClient.sendTransaction({
+ to: to_address,
+ value: parseEther(amount.toString()),
+ data: call_data,
+ gas,
+ });
+
+ return hash;
+}
+```
+
+```typescript ethers.js
+import { ethers } from "ethers";
+
+async function executeEvmDeposit(depositAction, privateKey) {
+ const { call_data, to_address, amount, network } = depositAction;
+
+ const provider = new ethers.JsonRpcProvider(network.node_url);
+ const wallet = new ethers.Wallet(privateKey, provider);
+
+ // Estimate gas
+ let gasLimit;
+ try {
+ gasLimit = await provider.estimateGas({
+ from: wallet.address,
+ to: to_address,
+ value: ethers.parseEther(amount.toString()),
+ data: call_data,
+ });
+ } catch (error) {
+ console.warn("Gas estimation failed, proceeding without explicit gas limit");
+ }
+
+ // Send transaction
+ const tx = await wallet.sendTransaction({
+ to: to_address,
+ value: ethers.parseEther(amount.toString()),
+ data: call_data,
+ gasLimit,
+ });
+
+ return tx.hash;
+}
+```
+
+```typescript wagmi
+import { sendTransaction } from "@wagmi/core";
+import { parseEther } from "viem";
+
+async function executeEvmDeposit(depositAction, wagmiConfig) {
+ const { call_data, to_address, amount, network } = depositAction;
+
+ const hash = await sendTransaction(wagmiConfig, {
+ chainId: Number(network.chain_id),
+ to: to_address,
+ value: parseEther(amount.toString()),
+ data: call_data,
+ });
+
+ return hash;
+}
+```
+
+
+
+ When using a browser wallet ([wagmi](https://wagmi.sh/)), ensure the user is connected to the correct chain (`network.chain_id`). If not, prompt them to switch networks before sending the transaction.
+
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/fuel.mdx b/api-reference/deposit-actions/fuel.mdx
new file mode 100644
index 0000000..4ce3a8e
--- /dev/null
+++ b/api-reference/deposit-actions/fuel.mdx
@@ -0,0 +1,200 @@
+---
+title: 'Fuel'
+description: 'Execute deposit transactions on the Fuel network using pre-built script transactions from call_data.'
+---
+
+## Overview
+
+Fuel deposits use a script-based transaction model. The Layerswap API returns a **pre-built script transaction** in `call_data` that you need to deserialize, fund with the required coin quantities, and submit.
+
+**Prerequisites:**
+- [fuels](https://docs.fuel.network/docs/fuels-ts/) (Fuel TypeScript SDK) for transaction construction and wallet interaction
+
+**Supported networks:** Fuel Mainnet, Fuel Testnet
+
+## call_data Format
+
+For Fuel, `call_data` is a **JSON string** containing two fields:
+
+```json
+{
+ "script": { /* ScriptTransactionRequest object */ },
+ "quantities": [
+ { "amount": "1000000", "assetId": "0x..." }
+ ]
+}
+```
+
+- `script` — A serialized `ScriptTransactionRequest` object containing the transaction script, inputs, outputs, and other parameters.
+- `quantities` — An array of coin quantities required to fund the transaction (covers the transfer amount and fees).
+
+## Transaction Construction
+
+
+
+ Deserialize the JSON string and extract the `script` and `quantities` fields.
+
+
+ Use `ScriptTransactionRequest.from()` to create a proper transaction request object from the serialized data.
+
+
+ Call `estimateAndFund()` on the transaction with the wallet and required quantities. This estimates gas costs and adds the necessary coin inputs.
+
+
+ Simulate the transaction against the Fuel provider to verify it will succeed before sending.
+
+
+ Submit the transaction through the Fuel wallet and get the transaction ID.
+
+
+
+## Full Example
+
+Pick the flavor that matches your setup. The `Server-side` tab signs with a raw private key. The `Browser` tab uses the Fuel Wallet extension via the Fuel connector. The `@fuels/react` tab wraps it as a hook for React apps.
+
+
+```typescript Server-side
+import {
+ Provider,
+ Wallet,
+ ScriptTransactionRequest,
+ coinQuantityfy,
+} from "fuels";
+
+async function executeFuelDeposit(
+ depositAction: any,
+ privateKey: string
+) {
+ const { call_data, network } = depositAction;
+
+ // Connect to the Fuel provider
+ const provider = new Provider(network.node_url);
+ const wallet = Wallet.fromPrivateKey(privateKey, provider);
+
+ // Parse the call_data
+ const parsedCallData = JSON.parse(call_data);
+
+ // Reconstruct the script transaction
+ const scriptTransaction = ScriptTransactionRequest.from(
+ parsedCallData.script
+ );
+
+ // Parse coin quantities
+ const quantities = parsedCallData.quantities.map((q: any) =>
+ coinQuantityfy(q)
+ );
+
+ // Estimate gas and fund the transaction with required coins
+ await scriptTransaction.estimateAndFund(wallet, { quantities });
+
+ // Simulate to verify (optional but recommended)
+ await provider.simulate(scriptTransaction);
+
+ // Send the transaction
+ const response = await wallet.sendTransaction(scriptTransaction);
+
+ return response.id;
+}
+```
+
+```typescript Browser
+import {
+ Provider,
+ ScriptTransactionRequest,
+ coinQuantityfy,
+} from "fuels";
+
+async function executeFuelDeposit(
+ depositAction: any,
+ fuel: any, // Fuel instance from @fuels/react
+ senderAddress: string
+) {
+ const { call_data, network } = depositAction;
+
+ const provider = new Provider(network.node_url);
+ const wallet = await fuel.getWallet(senderAddress, provider);
+
+ if (!wallet) {
+ throw new Error("Fuel wallet not found");
+ }
+
+ const parsedCallData = JSON.parse(call_data);
+ const scriptTransaction = ScriptTransactionRequest.from(
+ parsedCallData.script
+ );
+ const quantities = parsedCallData.quantities.map((q: any) =>
+ coinQuantityfy(q)
+ );
+
+ await scriptTransaction.estimateAndFund(wallet, { quantities });
+
+ // Simulate first
+ await provider.simulate(scriptTransaction);
+
+ // Send through the browser wallet
+ const response = await wallet.sendTransaction(scriptTransaction);
+
+ return response.id;
+}
+```
+
+```typescript @fuels/react
+import { useFuel } from "@fuels/react";
+import {
+ Provider,
+ ScriptTransactionRequest,
+ coinQuantityfy,
+} from "fuels";
+
+function useFuelDeposit() {
+ const { fuel } = useFuel();
+
+ async function executeDeposit(
+ depositAction: any,
+ senderAddress: string
+ ): Promise {
+ if (!fuel) {
+ throw new Error("Fuel not initialized");
+ }
+
+ const { call_data, network } = depositAction;
+
+ const provider = new Provider(network.node_url);
+ const wallet = await fuel.getWallet(senderAddress, provider);
+
+ if (!wallet) {
+ throw new Error("Fuel wallet not found");
+ }
+
+ const parsedCallData = JSON.parse(call_data);
+ const scriptTransaction = ScriptTransactionRequest.from(
+ parsedCallData.script
+ );
+ const quantities = parsedCallData.quantities.map((q: any) =>
+ coinQuantityfy(q)
+ );
+
+ await scriptTransaction.estimateAndFund(wallet, { quantities });
+ await provider.simulate(scriptTransaction);
+
+ const response = await wallet.sendTransaction(scriptTransaction);
+ return response.id;
+ }
+
+ return { executeDeposit };
+}
+```
+
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/overview.mdx b/api-reference/deposit-actions/overview.mdx
new file mode 100644
index 0000000..d5efb23
--- /dev/null
+++ b/api-reference/deposit-actions/overview.mdx
@@ -0,0 +1,118 @@
+---
+title: 'Handling Transfer Actions'
+description: 'Learn how to execute transfer transactions on different blockchains after creating a swap via the Layerswap API.'
+---
+
+## Overview
+
+When you create a swap via `POST /api/v2/swaps`, the response includes a `deposit_actions` array. Each transfer action contains the destination address, amount, and a blockchain-specific `call_data` payload — everything you need to construct and submit a transaction on the source chain. After broadcasting the transaction, you notify Layerswap with the transaction hash via the speedup endpoint so it can match the deposit and complete the swap.
+
+## Transfer Action Schema
+
+Each item in the `deposit_actions` array has the following structure:
+
+
+ Either `transfer` (wallet transaction) or `manual_transfer` (manual deposit to an address). Use the action with `type: "transfer"` for programmatic transfers.
+
+
+
+ The deposit address to send funds to.
+
+
+
+ The amount to transfer in human-readable units (e.g. `0.1` ETH, not wei).
+
+
+
+ The amount in the token's smallest unit (e.g. wei for ETH, satoshi for BTC).
+
+
+
+ Blockchain-specific payload used to construct the transaction. The format varies by chain — see the chain-specific guides below.
+
+
+
+ The source network object, including `name`, `type`, `chain_id`, and `node_url`.
+
+
+
+ The token being transferred, including `symbol`, `decimals`, and `contract` (null for native tokens).
+
+
+
+ The token used to pay transaction fees on this network.
+
+
+
+ Execution order if there are multiple transfer actions.
+
+
+## Step-by-Step Flow
+
+
+
+ Call `POST /api/v2/swaps` with `use_deposit_address: false` and include the `source_address` parameter. The response will contain `deposit_actions`.
+
+
+ Starknet, Paradex, and TON only support the transfer flow — `use_deposit_address: true` is rejected for these networks. All other source networks accept either mode.
+
+
+ ```bash
+ curl -X POST https://api.layerswap.io/api/v2/swaps \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "source_network": "ETHEREUM_MAINNET",
+ "source_token": "ETH",
+ "destination_network": "ARBITRUM_MAINNET",
+ "destination_token": "ETH",
+ "destination_address": "0xRecipient...",
+ "source_address": "0xSender...",
+ "amount": "0.1",
+ "use_deposit_address": false
+ }'
+ ```
+
+
+ From the response, find the transfer action with `type: "transfer"`:
+
+ ```javascript
+ const response = await createSwap(/* ... */);
+ const depositAction = response.deposit_actions.find(
+ action => action.type === "transfer"
+ );
+
+ const { call_data, to_address, amount, network, token } = depositAction;
+ ```
+
+
+ Use the `call_data`, `to_address`, and `amount` to construct and send a blockchain-specific transaction. See the chain guides below for implementation details.
+
+
+ After the transaction is submitted, call the speedup endpoint so Layerswap can match it faster:
+
+ ```bash
+ curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "0xYourTransactionHash..." }'
+ ```
+
+
+ Poll `GET /api/v2/swaps/{swap_id}` or use [webhooks](/api-reference/webhook) to track the swap through its [lifecycle](/api-reference/swap-lifecycle).
+
+
+
+## call_data Format by Chain
+
+The `call_data` field is the key piece — its format depends on the source blockchain:
+
+| Blockchain | call_data Format | Guide |
+|---|---|---|
+| EVM (Ethereum, Arbitrum, Base, etc.) | Hex-encoded transaction data (`0x...`) | [EVM Guide](/api-reference/deposit-actions/evm) |
+| Bitcoin | Numeric memo (encoded as OP_RETURN) | [Bitcoin Guide](/api-reference/deposit-actions/bitcoin) |
+| Solana | Base64-encoded serialized transaction | [Solana Guide](/api-reference/deposit-actions/solana) |
+| Starknet | JSON array of Starknet calls | [Starknet Guide](/api-reference/deposit-actions/starknet) |
+| TON | JSON object with `comment` (and `amount` for Jettons) | [TON Guide](/api-reference/deposit-actions/ton) |
+| Tron | String memo (hex-encoded into transaction data) | [Tron Guide](/api-reference/deposit-actions/tron) |
+| Fuel | JSON object with `script` and `quantities` | [Fuel Guide](/api-reference/deposit-actions/fuel) |
\ No newline at end of file
diff --git a/api-reference/deposit-actions/solana.mdx b/api-reference/deposit-actions/solana.mdx
new file mode 100644
index 0000000..5c8e750
--- /dev/null
+++ b/api-reference/deposit-actions/solana.mdx
@@ -0,0 +1,197 @@
+---
+title: 'Solana'
+description: 'Execute deposit transactions on Solana by deserializing and signing the pre-built transaction from call_data.'
+---
+
+## Overview
+
+Solana deposits are straightforward because the Layerswap API returns a **fully constructed, serialized transaction** in `call_data`. You only need to decode it, set a fresh blockhash, sign it, and send it.
+
+**Prerequisites:**
+- [@solana/web3.js](https://github.com/solana-foundation/solana-web3.js) for transaction handling and RPC communication
+
+## call_data Format
+
+For Solana, `call_data` is a **base64-encoded serialized `Transaction`**. It contains all the instructions, accounts, and program IDs already set up by the Layerswap backend — including SPL token transfers when applicable.
+
+```javascript
+// Node.js / server-side
+const buffer = Buffer.from(callData, "base64");
+const transaction = Transaction.from(buffer);
+
+// Browser
+const buffer = Uint8Array.from(atob(callData), (c) => c.charCodeAt(0));
+const transaction = Transaction.from(buffer);
+```
+
+## Transaction Construction
+
+
+
+ Convert the base64 `call_data` string into a `Transaction` object.
+
+
+ Fetch the latest blockhash from the Solana RPC and update the transaction. This ensures the transaction doesn't expire before it's confirmed.
+
+
+ Estimate the transaction fee and verify the sender has enough SOL for fees and enough of the source token for the transfer amount.
+
+
+ Sign the transaction with the sender's keypair or wallet adapter.
+
+
+ Submit the signed transaction to the network and wait for confirmation.
+
+
+
+## Full Example
+
+The `Server-side` tab signs locally with a `Keypair`. The `Browser` tab uses a connected wallet adapter (Phantom, Solflare, etc.) and its `signTransaction` method.
+
+
+```typescript Server-side
+import {
+ Connection,
+ Transaction,
+ Keypair,
+ LAMPORTS_PER_SOL,
+ sendAndConfirmTransaction,
+} from "@solana/web3.js";
+import bs58 from "bs58";
+
+async function executeSolanaDeposit(
+ depositAction: any,
+ senderKeypair: Keypair
+) {
+ const { call_data, network } = depositAction;
+
+ const connection = new Connection(network.node_url, "confirmed");
+
+ // Decode base64 call_data into a Transaction
+ const buffer = Buffer.from(call_data, "base64");
+ const transaction = Transaction.from(buffer);
+
+ // Set a fresh blockhash
+ const { blockhash, lastValidBlockHeight } =
+ await connection.getLatestBlockhash();
+ transaction.recentBlockhash = blockhash;
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
+
+ // Send and confirm
+ const signature = await sendAndConfirmTransaction(
+ connection,
+ transaction,
+ [senderKeypair],
+ { commitment: "confirmed" }
+ );
+
+ return signature;
+}
+```
+
+```typescript Browser
+import { Connection, Transaction, LAMPORTS_PER_SOL } from "@solana/web3.js";
+
+async function executeSolanaDeposit(
+ depositAction: any,
+ nodeUrl: string,
+ signTransaction: (tx: Transaction) => Promise
+) {
+ const { call_data } = depositAction;
+
+ const connection = new Connection(nodeUrl, "confirmed");
+
+ // Decode base64 call_data
+ const buffer = Uint8Array.from(atob(call_data), (c) => c.charCodeAt(0));
+ const transaction = Transaction.from(buffer);
+
+
+ // Set fresh blockhash
+ const blockHash = await connection.getLatestBlockhash();
+ transaction.recentBlockhash = blockHash.blockhash;
+ transaction.lastValidBlockHeight = blockHash.lastValidBlockHeight;
+
+ // Sign with wallet adapter
+ const signed = await signTransaction(transaction);
+
+ // Send the signed transaction
+ const rawTransaction = signed.serialize();
+ const txid = await connection.sendRawTransaction(rawTransaction, {
+ skipPreflight: true,
+ });
+
+ // Confirm
+ await connection.confirmTransaction(
+ {
+ signature: txid,
+ blockhash: blockHash.blockhash,
+ lastValidBlockHeight: blockHash.lastValidBlockHeight,
+ },
+ "confirmed"
+ );
+
+ return txid;
+}
+```
+
+
+## Sending with Retry Logic
+
+Solana transactions can sometimes fail to land due to network congestion. A robust implementation resends the transaction periodically until it's confirmed or the blockhash expires:
+
+```typescript
+import { Connection, Transaction } from "@solana/web3.js";
+
+async function sendWithRetry(
+ connection: Connection,
+ serializedTx: Buffer,
+ blockhash: string,
+ lastValidBlockHeight: number
+): Promise {
+ const txid = await connection.sendRawTransaction(serializedTx, {
+ skipPreflight: true,
+ });
+
+ const controller = new AbortController();
+
+ // Resend every 2 seconds in the background
+ const resendLoop = async () => {
+ while (!controller.signal.aborted) {
+ await new Promise((r) => setTimeout(r, 2000));
+ if (controller.signal.aborted) return;
+ try {
+ await connection.sendRawTransaction(serializedTx, {
+ skipPreflight: true,
+ });
+ } catch {
+ // Ignore resend errors
+ }
+ }
+ };
+ resendLoop();
+
+ try {
+ await connection.confirmTransaction(
+ { signature: txid, blockhash, lastValidBlockHeight },
+ "confirmed"
+ );
+ } finally {
+ controller.abort();
+ }
+
+ return txid;
+}
+```
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/starknet.mdx b/api-reference/deposit-actions/starknet.mdx
new file mode 100644
index 0000000..f0541c4
--- /dev/null
+++ b/api-reference/deposit-actions/starknet.mdx
@@ -0,0 +1,153 @@
+---
+title: 'Starknet'
+description: 'Execute deposit transactions on Starknet using the multicall format from call_data.'
+---
+
+## Overview
+
+Starknet deposits are simple to execute because the Layerswap API returns a **pre-built array of Starknet calls** in `call_data`. You parse the JSON and pass it directly to the account's `execute` method, which handles multicall execution natively.
+
+**Prerequisites:**
+- [starknet.js](https://github.com/starknet-io/starknet.js) for account interaction and transaction execution
+
+**Supported networks:** Starknet Mainnet, Starknet Sepolia
+
+## call_data Format
+
+For Starknet, `call_data` is a **JSON-encoded array of call objects**. Layerswap always returns **two calls**:
+
+1. A `transfer` call on the token contract (ETH on Starknet is also an ERC-20).
+2. A `watch` call on the Layerswap **Watchdog** contract, which the backend uses to match the deposit.
+
+```json
+[
+ {
+ "contractAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
+ "entrypoint": "transfer",
+ "calldata": ["0xRecipient", "0xAmountLow", "0xAmountHigh"]
+ },
+ {
+ "contractAddress": "0xWatchdogContract...",
+ "entrypoint": "watch",
+ "calldata": ["0xSequenceNumber"]
+ }
+]
+```
+
+Both calls must execute atomically — pass the whole array to `account.execute()` as shown below; Starknet handles them as a single multicall transaction.
+
+## Transaction Construction
+
+
+
+ Deserialize the JSON string into an array of Starknet call objects.
+
+
+ Pass the calls array to `account.execute()`. Starknet natively supports multicall, so all calls in the array are executed atomically in a single transaction.
+
+
+ The `execute` method returns an object with `transaction_hash`.
+
+
+
+## Full Example
+
+Pick the flavor that matches your setup. The `Server-side` tab signs with a raw private key via `starknet.js`. The `Browser` tab connects to an injected wallet like ArgentX or Braavos via `get-starknet`. The `starknet-react` tab wraps it as a hook for React apps.
+
+
+```typescript Server-side
+import { Account, RpcProvider, Call } from "starknet";
+
+async function executeStarknetDeposit(
+ depositAction: any,
+ senderAddress: string,
+ privateKey: string
+) {
+ const { call_data, network } = depositAction;
+
+ const provider = new RpcProvider({ nodeUrl: network.node_url });
+ const account = new Account(provider, senderAddress, privateKey);
+
+ // Parse the call_data JSON into Starknet calls
+ const calls: Call[] = JSON.parse(call_data);
+
+ // Execute the multicall transaction
+ const { transaction_hash } = await account.execute(calls);
+
+ if (!transaction_hash) {
+ throw new Error("No transaction hash returned");
+ }
+
+ // Optionally wait for confirmation
+ await provider.waitForTransaction(transaction_hash);
+
+ return transaction_hash;
+}
+```
+
+```typescript Browser
+import { connect } from "get-starknet";
+import { Call } from "starknet";
+
+async function executeStarknetDeposit(depositAction: any) {
+ const { call_data } = depositAction;
+
+ // Connect to wallet
+ const starknet = await connect();
+ if (!starknet?.isConnected || !starknet.account) {
+ throw new Error("Starknet wallet not connected");
+ }
+
+ // Parse the call_data JSON
+ const calls: Call[] = JSON.parse(call_data);
+
+ // Execute through the connected wallet
+ const { transaction_hash } = await starknet.account.execute(calls);
+
+ if (!transaction_hash) {
+ throw new Error("No transaction hash returned");
+ }
+
+ return transaction_hash;
+}
+```
+
+```typescript starknet-react
+import { useAccount } from "@starknet-react/core";
+import { Call } from "starknet";
+
+function useStarknetDeposit() {
+ const { account } = useAccount();
+
+ async function executeDeposit(depositAction: any): Promise {
+ if (!account) {
+ throw new Error("Starknet account not connected");
+ }
+
+ const calls: Call[] = JSON.parse(depositAction.call_data);
+ const { transaction_hash } = await account.execute(calls);
+
+ if (!transaction_hash) {
+ throw new Error("No transaction hash returned");
+ }
+
+ return transaction_hash;
+ }
+
+ return { executeDeposit };
+}
+```
+
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/ton.mdx b/api-reference/deposit-actions/ton.mdx
new file mode 100644
index 0000000..f02f191
--- /dev/null
+++ b/api-reference/deposit-actions/ton.mdx
@@ -0,0 +1,261 @@
+---
+title: 'TON'
+description: 'Execute deposit transactions on The Open Network for both native TON and Jetton (token) transfers.'
+---
+
+## Overview
+
+TON deposits require constructing a TON-specific message payload. The flow differs depending on whether you're transferring **native TON** or a **Jetton** (TRC-20-like token on TON). The `call_data` from the Layerswap API contains the information needed to build the correct payload.
+
+**Prerequisites:**
+- [@ton/ton](https://github.com/ton-org/ton) for cell building and TON client
+- [@tonconnect/ui-react](https://github.com/ton-connect/sdk) (for browser wallets) or a TON SDK for server-side signing
+
+## call_data Format
+
+For TON, `call_data` is a **JSON string** containing:
+
+```json
+{
+ "amount": "1000000000",
+ "asset": "TON",
+ "comment": "layerswap_memo_identifier"
+}
+```
+
+- `comment` — A text memo that Layerswap uses to identify the deposit. This is embedded in the transaction payload.
+- `amount` — The transfer amount in base units (nanotons for TON, base units of the Jetton otherwise). Always present; for native TON it matches the transfer action's `amount` field.
+- `asset` — The source asset symbol (e.g. `TON`, `USDT`). Informational; the actual contract is on the transfer action's `token.contract`.
+
+## Native TON Transfer
+
+For native TON transfers (when `token.contract` is null), the transaction is a simple message to the deposit address with a comment payload.
+
+### Transaction Construction
+
+
+
+ Extract the `comment` field from the JSON.
+
+
+ Create a TON cell with a 32-bit zero prefix (indicates a text comment) followed by the comment string.
+
+
+ Send a message to `to_address` with the deposit `amount` (converted to nanotons) and the comment cell as payload.
+
+
+
+### Full Example
+
+```typescript
+import { beginCell, toNano } from "@ton/ton";
+
+function buildNativeTonTransaction(
+ depositAction: any
+) {
+ const { call_data, to_address, amount } = depositAction;
+ const { comment } = JSON.parse(call_data);
+
+ const body = beginCell()
+ .storeUint(0, 32) // 0 opcode = text comment
+ .storeStringTail(comment)
+ .endCell();
+
+ return {
+ validUntil: Math.floor(Date.now() / 1000) + 360,
+ messages: [
+ {
+ address: to_address,
+ amount: toNano(amount).toString(),
+ payload: body.toBoc().toString("base64"),
+ },
+ ],
+ };
+}
+```
+
+## Jetton Transfer
+
+For Jetton transfers (when `token.contract` is not null), you need to build a Jetton transfer message that targets the sender's Jetton wallet address (not the Jetton master contract).
+
+### Transaction Construction
+
+
+
+ Extract both `comment` and `amount` from the JSON.
+
+
+ Use the Jetton master contract to look up the sender's Jetton wallet address via `get_wallet_address`.
+
+
+ Construct a cell with the Jetton transfer opcode (`0x0f8a7ea5`), the Jetton amount, the destination address, and a forward payload containing the comment.
+
+
+ Send the message to the sender's Jetton wallet address with enough TON attached to cover fees.
+
+
+
+### Full Example
+
+```typescript
+import {
+ Address,
+ JettonMaster,
+ TonClient,
+ beginCell,
+ toNano,
+} from "@ton/ton";
+
+async function buildJettonTransaction(
+ depositAction: any,
+ senderAddress: string,
+ tonClient: TonClient
+) {
+ const { call_data, to_address, token } = depositAction;
+ const { comment, amount: jettonAmount } = JSON.parse(call_data);
+
+ const destinationAddress = Address.parse(to_address);
+ const userAddress = Address.parse(senderAddress);
+
+ // Build the forward payload (comment)
+ const forwardPayload = beginCell()
+ .storeUint(0, 32)
+ .storeStringTail(comment)
+ .endCell();
+
+ // Build the Jetton transfer body
+ const body = beginCell()
+ .storeUint(0x0f8a7ea5, 32) // Jetton transfer opcode
+ .storeUint(0, 64) // query_id
+ .storeCoins(BigInt(jettonAmount)) // Jetton amount in base units
+ .storeAddress(destinationAddress) // destination
+ .storeAddress(destinationAddress) // response excess destination
+ .storeBit(0) // no custom payload
+ .storeCoins(toNano("0.00002")) // forward amount for notification
+ .storeBit(1) // forward payload as reference
+ .storeRef(forwardPayload)
+ .endCell();
+
+ // Resolve the sender's Jetton wallet address
+ const jettonMasterAddress = Address.parse(token.contract);
+ const jettonMaster = tonClient.open(
+ JettonMaster.create(jettonMasterAddress)
+ );
+ const jettonWalletAddress =
+ await jettonMaster.getWalletAddress(userAddress);
+
+ return {
+ validUntil: Math.floor(Date.now() / 1000) + 360,
+ messages: [
+ {
+ address: jettonWalletAddress.toString(),
+ amount: toNano("0.045").toString(), // TON for fees; excess is returned
+ payload: body.toBoc().toString("base64"),
+ },
+ ],
+ };
+}
+```
+
+## Sending the Transaction
+
+The `TON Connect` tab is for browser wallets like Tonkeeper or MyTonWallet — it picks between the native and Jetton builders above based on `token.contract`. The `Server-side` tab signs and sends directly with a wallet key for backend use.
+
+
+```typescript TON Connect
+import { TonConnectUI } from "@tonconnect/ui-react";
+import { TonClient } from "@ton/ton";
+
+async function executeTonDeposit(
+ depositAction: any,
+ senderAddress: string,
+ tonConnectUI: TonConnectUI,
+ tonClient: TonClient
+) {
+ const { token } = depositAction;
+ let transaction;
+
+ if (token.contract) {
+ transaction = await buildJettonTransaction(
+ depositAction,
+ senderAddress,
+ tonClient
+ );
+ } else {
+ transaction = buildNativeTonTransaction(depositAction);
+ }
+
+ const result = await tonConnectUI.sendTransaction(transaction);
+
+ // result.boc contains the sent message BOC
+ // You can use it to track the transaction on-chain
+ return result.boc;
+}
+```
+
+```typescript Server-side
+import {
+ WalletContractV4,
+ internal,
+ TonClient,
+ beginCell,
+ toNano,
+} from "@ton/ton";
+import { mnemonicToPrivateKey } from "@ton/crypto";
+
+async function executeTonDepositServerSide(
+ depositAction: any,
+ mnemonic: string[]
+) {
+ const { call_data, to_address, amount, network } = depositAction;
+ const { comment } = JSON.parse(call_data);
+
+ const tonClient = new TonClient({
+ endpoint: network.node_url,
+ });
+
+ const keyPair = await mnemonicToPrivateKey(mnemonic);
+ const wallet = WalletContractV4.create({
+ publicKey: keyPair.publicKey,
+ workchain: 0,
+ });
+
+ const contract = tonClient.open(wallet);
+
+ const body = beginCell()
+ .storeUint(0, 32)
+ .storeStringTail(comment)
+ .endCell();
+
+ await contract.sendTransfer({
+ seqno: await contract.getSeqno(),
+ secretKey: keyPair.secretKey,
+ messages: [
+ internal({
+ to: to_address,
+ value: toNano(amount),
+ body,
+ bounce: false,
+ }),
+ ],
+ });
+}
+```
+
+
+
+ The server-side example above shows a native TON transfer. For Jetton transfers, build the Jetton cell as shown in the Jetton section and target the sender's Jetton wallet address.
+
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
\ No newline at end of file
diff --git a/api-reference/deposit-actions/tron.mdx b/api-reference/deposit-actions/tron.mdx
new file mode 100644
index 0000000..aa336c6
--- /dev/null
+++ b/api-reference/deposit-actions/tron.mdx
@@ -0,0 +1,147 @@
+---
+title: 'Tron'
+description: 'Execute deposit transactions on Tron for TRC-20 token transfers.'
+---
+
+## Overview
+
+Tron deposits require building a TRC-20 token transfer transaction using TronWeb, then appending the `call_data` as hex-encoded data before signing and broadcasting.
+
+**Prerequisites:**
+- [tronweb](https://github.com/tronprotocol/tronweb) for transaction building and RPC communication
+
+**Supported networks:** Tron Mainnet, Tron Testnet (Shasta/Nile)
+
+## call_data Format
+
+For Tron, `call_data` is a **plain string** (a memo identifier). It is converted to hex and embedded in the transaction data field:
+
+```javascript
+const hexData = Buffer.from(callData).toString("hex");
+```
+
+This hex data is appended to the transaction using TronWeb's `addUpdateData` method, which Layerswap uses to identify and match the deposit.
+
+## Full Example
+
+The `Server-side` tab signs with a raw private key. The `Browser` tab uses a Tron wallet adapter (TronLink, etc.) and its `signTransaction` method.
+
+
+```typescript Server-side
+import { TronWeb } from "tronweb";
+
+async function executeTronDeposit(
+ depositAction: any,
+ senderAddress: string,
+ privateKey: string
+) {
+ const { call_data, to_address, amount, token, network } = depositAction;
+
+ const tronWeb = new TronWeb({
+ fullNode: network.node_url,
+ solidityNode: network.node_url,
+ privateKey,
+ });
+
+ const amountInBaseUnits = Math.floor(
+ amount * Math.pow(10, token.decimals)
+ );
+
+ // Build the TRC-20 transfer via smart contract
+ const { transaction: initialTransaction } =
+ await tronWeb.transactionBuilder.triggerSmartContract(
+ token.contract,
+ "transfer(address,uint256)",
+ {
+ feeLimit: 100_000_000, // 100 TRX fee limit
+ },
+ [
+ { type: "address", value: to_address },
+ { type: "uint256", value: amountInBaseUnits },
+ ],
+ senderAddress
+ );
+
+ // Append call_data as hex data
+ const hexData = Buffer.from(call_data).toString("hex");
+ const transaction = await tronWeb.transactionBuilder.addUpdateData(
+ initialTransaction,
+ hexData,
+ "hex"
+ );
+
+ // Sign and broadcast
+ const signedTransaction = await tronWeb.trx.sign(transaction);
+ const result = await tronWeb.trx.sendRawTransaction(signedTransaction);
+
+ if (result.result) {
+ return signedTransaction.txID;
+ }
+
+ throw new Error("Transaction broadcast failed");
+}
+```
+
+```typescript Browser
+import { TronWeb } from "tronweb";
+
+async function executeTronDeposit(
+ depositAction: any,
+ senderAddress: string,
+ signTransaction: (tx: any) => Promise
+) {
+ const { call_data, to_address, amount, token, network } = depositAction;
+
+ const tronWeb = new TronWeb({
+ fullNode: network.node_url,
+ solidityNode: network.node_url,
+ });
+
+ const amountInBaseUnits = Math.floor(
+ amount * Math.pow(10, token.decimals)
+ );
+
+ const { transaction: initialTransaction } =
+ await tronWeb.transactionBuilder.triggerSmartContract(
+ token.contract,
+ "transfer(address,uint256)",
+ { feeLimit: 100_000_000 },
+ [
+ { type: "address", value: to_address },
+ { type: "uint256", value: amountInBaseUnits },
+ ],
+ senderAddress
+ );
+
+ const hexData = Buffer.from(call_data).toString("hex");
+ const transaction = await tronWeb.transactionBuilder.addUpdateData(
+ initialTransaction,
+ hexData,
+ "hex"
+ );
+
+ // Sign using the wallet adapter
+ const signedTransaction = await signTransaction(transaction);
+ const result = await tronWeb.trx.sendRawTransaction(signedTransaction);
+
+ if (result.result) {
+ return signedTransaction.txID;
+ }
+
+ throw new Error("Transaction broadcast failed");
+}
+```
+
+
+## Next Step
+
+After the transaction is submitted, notify Layerswap so it can match your deposit faster:
+
+```bash
+curl -X POST https://api.layerswap.io/api/v2/swaps/{swap_id}/deposit_speedup \
+ -H "X-LS-APIKEY: your_api_key" \
+ -H "Content-Type: application/json" \
+ -d '{ "transaction_id": "YOUR_TX_HASH" }'
+```
+
+See the [full deposit flow](/api-reference/deposit-actions/overview) for details.
diff --git a/docs.json b/docs.json
index c4b3807..a5d844a 100644
--- a/docs.json
+++ b/docs.json
@@ -147,6 +147,24 @@
"recipes/privy-wallets"
]
},
+ {
+ "group": "Transfer Actions",
+ "pages": [
+ "api-reference/deposit-actions/overview",
+ {
+ "group": "Blockchains",
+ "pages": [
+ "api-reference/deposit-actions/evm",
+ "api-reference/deposit-actions/bitcoin",
+ "api-reference/deposit-actions/solana",
+ "api-reference/deposit-actions/starknet",
+ "api-reference/deposit-actions/ton",
+ "api-reference/deposit-actions/tron",
+ "api-reference/deposit-actions/fuel"
+ ]
+ }
+ ]
+ },
{
"group": "Endpoints",
"openapi": {
diff --git a/integration/API.mdx b/integration/API.mdx
index 47514b3..ecf7b8e 100644
--- a/integration/API.mdx
+++ b/integration/API.mdx
@@ -19,11 +19,8 @@ Layerswap handles millions of dollars in transactions every day across multiple
Create Swap using the Layerswap API.
-
- Layerswap will monitor the source network for a transaction and will try to match it with the corresponding swap
-
-
- Once the transaction is matched and added to the swap, Layerswap will initiate a counterparty transaction to the destination_address
+
+ Use the `deposit_actions` from the swap response to submit a transaction on the source chain. See [Handling Deposits](/api-reference/deposit-actions/overview) for chain-specific guides.
Poll via Get Swap endpoint to see if the matching transaction Input was added to the swap