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

# SEP-6: Deposit and Withdrawal API

> SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site.

SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet and submitted to the anchor *on behalf of* the user.

## Find the anchor's `TRANSFER_SERVER`

Before we can ask anything about *how* to make a SEP-6 transfer, we have to figure out *where* to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need.

```js title=/src/lib/stellar/sep1.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Fetches and returns the endpoint used for SEP-6 transfer interactions.
export async function getTransferServerSep6(domain) {
  let { TRANSFER_SERVER } = await fetchStellarToml(domain);
  return TRANSFER_SERVER;
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js)

## Get `/info`

Now that we know where the transfer server is located, BasicPay needs to fetch the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md#info)) and available endpoints, as well as additional features that may be available during transfers.

> [!NOTE]
>
> At this time, BasicPay only supports the `deposit` and `withdraw` transfer methods. A future version of this tutorial will incorporate the `*-exchange` transfer methods.

```js title=/src/lib/stellar/sep6.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { getTransferServerSep6 } from "$lib/stellar/sep1";

// Fetches and returns basic information about what the SEP-6 transfer server suppports.
export async function getSep6Info(domain) {
  let transferServer = await getTransferServerSep6(domain);
  let res = await fetch(`${transferServer}/info`);
  let json = await res.json();
  return json;
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js)

## Display interactive elements

Since many of the SEP-6 (and SEP-24) endpoints require authentication, we wait until our user is [authenticated with SEP-10](https://developers.stellar.org/docs/build/apps/example-application-tutorial/anchor-integration/sep10.md) before we display what kinds of transfers are available. When they have a valid authentication token, we can display some buttons the user can use to begin a transfer.

The user can then initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by clicking the “Deposit” or “Withdraw” button underneath a supported asset.

![sep6](https://mintcdn.com/stellardevelopmentfoundation/1iVxlvEjme-PeN5h/assets/basic-pay/sep6_deposit_withdraw.png?fit=max\&auto=format\&n=1iVxlvEjme-PeN5h\&q=85\&s=eda52bbc19d5bd4bc60db9db32e68c04)

```html title=/src/routes/dashboard/transfers/+page.svelte theme={"theme":{"light":"github-light","dark":"github-dark"}}
<script>
  /* This <script> tag has been abbreviated for simplicity */

  // We import things from external packages that will be needed
  import { LogInIcon, LogOutIcon } from "svelte-feather-icons";

  // We import some of our `$lib` functions
  import { getSep6Info } from "$lib/stellar/sep6";

  // The `open` Svelte context is used to open the confirmation modal
  import { getContext } from "svelte";
  const { open } = getContext("simple-modal");

  /* ... */
</script>

<!-- HTML has been omitted from this tutorial. Please check the source file -->
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte)

## A special SEP-6 modal component

If you recall back to our [confirmation modal section](https://developers.stellar.org/docs/build/apps/example-application-tutorial/confirmation-modal.md), we designed our modal component to be useful for anything we might require. Well, that's *almost* true. The fact is that SEP-6 interactions are just plain complex. To facilitate that complexity, we've created a purpose-built SEP-6 transfer modal. There is **so much** to it, that we couldn't possibly cover everything it does here. However, we'll cover the main bits and link to the relevant source files.

The modal component itself has been broken into several smaller Svelte components. Check out this source file to start looking through how we've put it together: [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferModalSep6.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferModalSep6.svelte)

### Launching the SEP-6 modal

The above buttons will use the `launchTransferModalSep6` function to display the modal to the user. Here's how it's defined in that same file.

```html title=/src/routes/dashboard/transfers/+page.svelte theme={"theme":{"light":"github-light","dark":"github-dark"}}
<script>
  /* This <script> tag has been abbreviated for simplicity */

  // We import any Svelte components we will need
  import TransferModalSep6 from "./components/TransferModalSep6.svelte";

  // Launch the SEP-6 modal to begin the transfer process and gather information from the user.
  const launchTransferModalSep6 = ({
    homeDomain,
    assetCode,
    assetIssuer,
    endpoint,
    sep6Info,
  }) => {
    // Open the SEP-6 transfer modal, supplying the relevant props for our
    // desired type of transfer.
    open(TransferModalSep6, {
      homeDomain: homeDomain,
      assetIssuer: assetIssuer,
      transferData: {
        endpoint: endpoint,
      },
      formData: {
        account: data.publicKey,
        asset_code: assetCode,
      },
      sep6Info: sep6Info,
      // This `submitPayment` function is described later on.
      submitPayment: submitPayment,
    });
  };
</script>

<!-- HTML has been omitted from this tutorial. Please check the source file -->
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte)

Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and ultimately create the transfer.

### Modal step 1: Transfer details

BasicPay prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose.

We'll spare the code sample in this section, since it's mostly Svelte things going on. You can view the source here: [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferDetails.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferDetails.svelte)

![SEP-6 transfer details screen](https://mintcdn.com/stellardevelopmentfoundation/tVnwkp5PnLq75MWG/assets/basic-pay/sep6_transfer_details.png?fit=max\&auto=format\&n=tVnwkp5PnLq75MWG\&q=85\&s=fd4dd2ff633cc6232de6b9ff7e11162a)

### Modal step 2: Gather KYC information

To find out what infrastructure the anchor has made available for us to use, we need to query the anchor's SEP-1 `stellar.toml` file for the `KYC_SERVER` field. If this is not defined, BasicPay will fallback to using the `TRANSFER_SERVER` for these requests.

```js title=/src/lib/stellar/sep1.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Fetches and returns the endpoint used for SEP-12 KYC interactions.
export async function getKycServer(domain) {
  let { KYC_SERVER, TRANSFER_SERVER } = await fetchStellarToml(domain);
  // If `KYC_SERVER` is undefined in the domain's TOML file, `TRANSFER_SERVER`
  // will be used
  return KYC_SERVER ?? TRANSFER_SERVER;
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js)

Our SEP-6 modal then queries the anchor’s SEP-12 endpoint for the required KYC fields with a `GET` request, and we present these fields for the user to complete.

![SEP-6 KYC Screen](https://mintcdn.com/stellardevelopmentfoundation/tVnwkp5PnLq75MWG/assets/basic-pay/sep6_kyc.png?fit=max\&auto=format\&n=tVnwkp5PnLq75MWG\&q=85\&s=8db8c3525b012ac5a8b630124dc8f563)

```js title=/src/lib/stellar/sep12.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { getKycServer } from "$lib/stellar/sep1";

// Sends a `GET` request to query KYC status for a customer, returns current status of KYC submission
export async function getSep12Fields({ authToken, homeDomain }) {
  let kycServer = await getKycServer(homeDomain);

  let res = await fetch(`${kycServer}/customer`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${authToken}`,
    },
  });
  let json = await res.json();

  return json;
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js)

Again, the presentation of the fields the user must complete is more on the Svelte side of things, so we won't share those details here. However, the source for this component is available here: [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte)

### Modal step 3: Put KYC fields and report status

Now that the user has provided the necessary information for the KYC requirements of the anchor, we can submit them to the anchor's KYC server with a `PUT` request.

```js title=/src/lib/stellar/sep12.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Sends a `PUT` request to the KYC server, submitting the supplied fields for the customer's record.
export async function putSep12Fields({ authToken, fields, homeDomain }) {
  let kycServer = await getKycServer(homeDomain);

  let res = await fetch(`${kycServer}/customer`, {
    method: "PUT",
    mode: "cors",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${authToken}`,
    },
    body: JSON.stringify(fields),
  });
  let json = await res.json();

  return json;
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js)

BasicPay receives back from the anchor a status message for the user to see. Once the status message is `ACCEPTED`, we can finally submit the actual transfer request!

![KYC Accepted](https://mintcdn.com/stellardevelopmentfoundation/tVnwkp5PnLq75MWG/assets/basic-pay/kyc_accepted.png?fit=max\&auto=format\&n=tVnwkp5PnLq75MWG\&q=85\&s=ee3f546e2cfdb1935339d544d9686b92)

This component of the SEP-6 modal, like most of them, is almost entirely Svelte-related. So as to keep this tutorial (somewhat) uncluttered, we'll refer you to the source for the component, which you can find here: [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCStatus.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCStatus.svelte)

### Modal step 4: Submit transfer

BasicPay makes this request by taking all the fields that have been collected during this process and wrapping them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J\&asset_code=SRT\&type=bank_account\&amount=11)

We submit a `GET` request to the URL with our authorization token in the headers, and the anchor takes it from there!

```js title=/src/lib/stellar/sep6.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Initiates a transfer using the SEP-6 protocol.
export async function initiateTransfer6({
  authToken,
  endpoint,
  formData,
  domain,
}) {
  let transferServer = await getTransferServerSep6(domain);
  let searchParams = new URLSearchParams(formData);

  let res = await fetch(`${transferServer}/${endpoint}?${searchParams}`, {
    method: "GET",
    mode: "cors",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${authToken}`,
    },
  });
  let json = await res.json();

  if (!res.ok) {
    throw error(res.status, {
      message: json.error,
    });
  } else {
    return json;
  }
}
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js](https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js)

We then store the details of the transfer in the `transfersStore` store and display the transfer server's response to the user. We then wait for them to close the modal.

> [!NOTE]
>
> The only reason we're storing anything about the transfer in BasicPay is to help us keep track of which anchors the user has initiated transfers with. Otherwise, we wouldn't be able query for a transfer history (like on the `/dashboard` page).

### (Sometimes) Modal step 5: Send a Stellar payment

In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that *is* so good at so many things!

```html title=/src/routes/dashboard/transfers/+page.svelte theme={"theme":{"light":"github-light","dark":"github-dark"}}
<script>
  /* This <script> tag has been abbreviated for simplicity */

  // Define some component variables that will be used throughout the page
  let paymentXDR = "";
  let paymentNetwork = "";

  // After a withdraw transaction has been presented to the user, and they've confirmed with the correct pincode, sign and submit the transaction to the Stellar network.
  const onPaymentConfirm = async (pincode) => {
    // Use the walletStore to sign the transaction
    let signedTransaction = await walletStore.sign({
      transactionXDR: paymentXDR,
      network: paymentNetwork,
      pincode: pincode,
    });
    // Submit the transaction to the Stellar network
    await submit(signedTransaction);
  };

  // Builds a Stellar payment to present to the user which will complete a transfer to the Anchor.
  let submitPayment = async ({
    withdrawDetails,
    assetCode,
    assetIssuer,
    amount,
  }) => {
    let { transaction, network_passphrase } = await createPaymentTransaction({
      source: data.publicKey,
      destination: withdrawDetails.account_id,
      asset: `${assetCode}:${assetIssuer}`,
      amount: amount,
      memo: withdrawDetails.memo
        ? Buffer.from(withdrawDetails.memo, "base64")
        : undefined,
    });

    // Set the component variables to hold the transaction details
    paymentXDR = transaction;
    paymentNetwork = network_passphrase;

    // We close the SEP-6 modal, and open the regular confirmation modal
    close();
    open(ConfirmationModal, {
      transactionXDR: paymentXDR,
      transactionNetwork: paymentNetwork,
      onConfirm: onPaymentConfirm,
    });
  };

  /* ... */
</script>

<!-- HTML has been omitted from this tutorial. Please check the source file -->
```

**Source:** [https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte](https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte)
