> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerswap.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Fund via the Depository contract

> Create and fund a swap through the Depository using the contract call returned by the API.

For supported routes, the API returns a Depository contract address and encoded call that a wallet or smart contract can use to fund the swap. This method works well for server wallets, batched calls, and sponsored transactions. The EVM contract has been [audited by Hexens](https://hexens.io/audit-reports/layerswap-depository-mar-2026).

## Create the swap

```bash theme={null}
curl --request POST 'https://api.layerswap.io/api/v2/swaps' \
  --header 'Content-Type: application/json' \
  --header 'X-LS-APIKEY: YOUR_API_KEY' \
  --data '{
    "source_network": "ETHEREUM_MAINNET",
    "source_token": "USDC",
    "destination_network": "ARBITRUM_MAINNET",
    "destination_token": "USDC",
    "destination_address": "0xRecipient",
    "refund_address": "0xSourceNetworkRefundAddress",
    "amount": 100,
    "use_depository": true
  }'
```

## Depository action fields

The response includes `deposit_actions`. For the contract action:

<ResponseField name="to_address" type="string">
  Depository contract address and, for ERC-20 deposits, the approval spender.
</ResponseField>

<ResponseField name="call_data" type="string">
  Encoded deposit call to submit unchanged.
</ResponseField>

<ResponseField name="encoded_args" type="string[] | null">
  Function argument values in call order. Use them to reconstruct the contract call when needed.
</ResponseField>

<ResponseField name="amount_in_base_units" type="string">
  Native transaction value in base units. This is normally `0` for an ERC-20 call.
</ResponseField>

<ResponseField name="gas_limit" type="string | null">
  Gas estimate returned by the API, when available.
</ResponseField>

The API response is authoritative for the target and arguments.

## Approve and submit the deposit action

<Tabs>
  <Tab title="EVM (viem)">
    ```ts viem theme={null}
    import { createWalletClient, custom, parseAbi } from 'viem';

    // `swap` is the POST /api/v2/swaps response
    const action = swap.deposit_actions[0];
    const wallet = createWalletClient({ transport: custom(window.ethereum) });

    // ERC-20 only: approve the Depository (to_address) to pull the tokens.
    // The amount is the 4th depositERC20 argument, returned in encoded_args.
    if (action.token.contract) {
      await wallet.writeContract({
        address: action.token.contract,
        abi: parseAbi(['function approve(address spender, uint256 amount) returns (bool)']),
        functionName: 'approve',
        args: [action.to_address, BigInt(action.encoded_args[3])],
      });
    }

    // Submit the prepared depositNative / depositERC20 call exactly as returned
    await wallet.sendTransaction({
      to: action.to_address, // the Depository contract
      data: action.call_data,
      value: BigInt(action.amount_in_base_units), // 0 for ERC-20, the deposit amount for native
    });
    ```

    For native deposits, the approval is skipped and the returned `amount_in_base_units` is sent as `value`. Never replace the swap ID, receiver, or target embedded in `call_data`.
  </Tab>

  <Tab title="Tron (TronWeb)">
    On Tron, the Depository supports TRC-20 actions. Approve `action.to_address`, wait for the approval to confirm, then call `depositERC20` with the returned `encoded_args`:

    ```ts TronWeb theme={null}
    import { TronWeb } from 'tronweb';

    async function executeTronDepository(action, privateKey, waitForConfirmation) {
      const [id, , receiverHex, amountHex] = action.encoded_args; // [id, token, receiver, amount]
      const amount = BigInt(amountHex).toString();
      const tronWeb = new TronWeb({
        fullNode: action.network.node_url,
        solidityNode: action.network.node_url,
        privateKey,
      });
      const sender = tronWeb.defaultAddress.base58;

      // encoded_args carry EVM-style hex addresses — convert the receiver to a Tron address
      const receiver = tronWeb.address.fromHex(
        `41${receiverHex.replace(/^0x/, '')}`,
      );

      // 1) Approve the Depository (to_address) to spend the TRC-20 amount
      const approve = (await tronWeb.transactionBuilder.triggerSmartContract(
        action.token.contract,
        'approve(address,uint256)',
        { feeLimit: 100_000_000 },
        [
          { type: 'address', value: action.to_address },
          { type: 'uint256', value: amount },
        ],
        sender,
      )).transaction;
      const signedApprove = await tronWeb.trx.sign(approve);
      const approvalResult = await tronWeb.trx.sendRawTransaction(signedApprove);
      if (!approvalResult.result) throw new Error('TRC-20 approval failed');
      await waitForConfirmation(signedApprove.txID);

      // 2) Call depositERC20(bytes32 id, address token, address receiver, uint256 amount)
      //    on the Depository, after the approval confirms
      const deposit = (await tronWeb.transactionBuilder.triggerSmartContract(
        action.to_address,
        'depositERC20(bytes32,address,address,uint256)',
        { feeLimit: 100_000_000 },
        [
          { type: 'bytes32', value: id },
          { type: 'address', value: action.token.contract },
          { type: 'address', value: receiver },
          { type: 'uint256', value: amount },
        ],
        sender,
      )).transaction;
      const signedDeposit = await tronWeb.trx.sign(deposit);
      const depositResult = await tronWeb.trx.sendRawTransaction(signedDeposit);
      if (!depositResult.result) throw new Error('Depository transaction failed');
      return signedDeposit.txID;
    }
    ```
  </Tab>
</Tabs>

The examples' `feeLimit` and gas values are caps, not estimates — set them according to your execution policy. Do not reorder or replace the returned arguments.

## Detect the deposit

Store the submitted transaction hash, then use [`GET /swaps/by_transaction_hash/{hash}`](/api-reference/swaps/get-swap-by-transaction-hash) or [`GET /swaps/{id}`](/api-reference/swaps/get-swap-details). The swap then follows the normal [lifecycle](/concepts/swap-lifecycle).

See the [Privy server wallets recipe](/api/recipes/privy-wallets) for batching approval and deposit in a sponsored server-wallet flow.
