> ## 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.

# Programmatic Deposit and Withdrawal

> The [SEP-6] standard defines a way for anchors and wallets to interact on behalf of users.

> [!NOTE]
>
> This guide is available on four different programming languages: Typescript, Kotlin, Flutter (Dart) and Swift. You can change the shown version on each page via the buttons above.

> [!CAUTION]
>
> **Important**
>
> Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete.

> [!WARNING]
>
> **Important**
>
> Documentation for Kotlin is currently work in progress. Some of information may not be applicable for Kotlin, or missing. Code samples may be incomplete.

The [SEP-6] standard defines a way for anchors and wallets to interact on behalf of users. Wallets use this standard to facilitate exchanges between on-chain assets (such as stablecoins) and off-chain assets (such as fiat, or other network assets such as BTC).

Please note, this is for *programmatic* deposits and withdrawals. For hosted deposits and withdrawals, where the anchor interacts with wallets interactively using a popup, please see [Hosted Deposit and Withdrawal](https://developers.stellar.org/docs/build/apps/wallet/sep24.md).

## Get Anchor Information

Let's start with creating a sep6 object, which we'll use for all SEP-6 interactions:

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const sep6 = anchor.sep6();
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var sep6 = anchor.sep6();
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let sep6 = anchor.sep6
> ```

First, let's get information about the anchor's support for [SEP-6]. This request doesn't require authentication, and will return generic info, such as supported currencies, and features supported by the anchor. You can get a full list of returned fields in the [SEP-6 specification](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md#info).

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const info = await sep6.info();
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var info = await sep6.info();
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let info = try await sep6.info()
> ```

## Start a deposit

Before getting started, make sure you have connected to the anchor and received an authentication token, as described in the [Stellar Authentication] wallet guide. We will use `authToken` in the examples below as the [SEP-10] authentication token, obtained earlier.

To initiate an operation, we need to know an asset. You can hardcode this. Ensure it is one that is included in the info response above.

> [!NOTE]
>
> Before starting with the deposit flow, make sure that the user account has [established a trustline](https://developers.stellar.org/docs/build/apps/wallet/stellar.md#modify-assets-trustlines) for the asset you are working with.

Let's start with a basic deposit. We will use `account` to represent our account's public key.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const deposit = await sep6.deposit({
>   authToken,
>   params: {
>     asset_code,
>     account,
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var deposit = await anchor.sep6().deposit(
>   Sep6DepositParams(assetCode: assetCode, account: accountId),
>   authToken,
> );
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let params = Sep6DepositParams(assetCode: assetCode, account: account)
> let depositResponse = try await anchor.sep6.deposit(params: params, authToken: authToken)
>
> switch depositResponse {
> case .depositSuccess(let how, let id, let eta, let minAmount, let maxAmount, let feeFixed, let feePercent, let extraInfo, let instructions):
>  // ...
> }
> ```

There are several kinds of responses, depending on if the anchor needs more information. All deposits and withdrawals will have these same response types:

### 1. Success response

If the response is successful (HTTP 200), then the anchor is processing the deposit. If it needs additional information, it will communicate it when providing the [transaction info](#getting-transaction-info).

### 2. Still processing, or denied

If an HTTP 403 with data: `customer_info_status` is returned, it means the action is still processing, or not accepted. In this case the `more_info_url` field should have a link describing next steps.

An example response:

```
{
  "type": "customer_info_status",
  "status": "denied",
  "more_info_url": "https://api.example.com/kycstatus?account=GACW7NONV43MZIFHCOKCQJAKSJSISSICFVUJ2C6EZIW5773OU3HD64VI"
}
```

### 3. Needs more KYC info

Another common response is an HTTP 403, with the response: `non_interactive_customer_info_needed`. In this case the anchor needs more KYC information via [SEP-12].

An example response:

```
{
  "type": "non_interactive_customer_info_needed",
  "fields" : ["family_name", "given_name", "address", "tax_id"]
}
```

Let's show how a wallet can handle this situation. First, we get the deposit response object. If the response includes this error, then we can see which missing fields the anchor is requiring.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> if (deposit.type === "non_interactive_customer_info_needed") {
>   // handle displaying the missing fields to the user
>   console.log(deposit.fields);
> }
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> if (deposit is Sep6MissingKYC) {
>   print(deposit.fields);
> }
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> switch depositResponse {
> case .missingKYC(let fields):
>    //...
> }
> ```

The wallet will need to handle displaying to the user which fields are missing. And then to add those fields, we can use the sep12 class like so.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const sep12 = await anchor.sep12(authToken);
>
> // adding the missing kyc info (sample data)
> await sep12.add({
>   sep9Info: {
>     family_name: "smith",
>     given_name: "john",
>     address: "123 street",
>     tax_id: "123",
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var sep12 = await anchor.sep12(authToken);
>
> // adding the missing kyc info (sample data)
> var sep9Info = {
>   'family_name': 'smith',
>   'given_name': 'john',
>   'address': '123 street',
>   'tax_id': '123',
> };
>
> var addResponse = await sep12.add(sep9Info);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let sep12 = try await anchor.sep12(authToken: authToken)
>
> // adding the missing kyc info (sample data)
> let sep9Info = [
>  "family_name" : "smith",
>  "given_name" : "john",
>  "address" : "123 street",
>  "tax_id": "123",
> ]
>
> let addResponse = try await sep12.add(sep9Info: sep9Info)
> ```

Then, we can re-call the deposit method like before and it should be successful.

More information about sending KYC info using [SEP-12] can be found in [Providing KYC info](#providing-kyc-info).

## Providing KYC info

An anchor may respond to a deposit or withdrawal request saying they need additional KYC info. To faciliate this, [SEP-6] supports adding a customer's KYC info via [SEP-12]. The user can send in the required info using the sep12 object like below.

Let's add some KYC info for our account using sample data. Binary data (eg. image data), needs to be sent in a separate field. The fields allowed to send to the anchor are described in [SEP-9].

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const sep12 = await anchor.sep12(authToken);
>
> await sep12.add({
>   sep9Info: {
>     first_name: "john",
>     last_name: "smith",
>     email_address: "123@gmail.com",
>     bank_number: "12345",
>     bank_account_number: "12345",
>   },
>   sep9BinaryInfo: {
>     photo_id_front: Buffer.from("./path/to/image/front"),
>     photo_id_back: Buffer.from("./path/to/image/back"),
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var sep12 = await anchor.sep12(authToken);
>
> var sep9Info = {
>   'first_name': 'john',
>   'last_name': 'smith',
>   'email_address': '123@gmail.com',
>   'bank_number': '12345',
>   'bank_account_number': '12345',
> };
>
> var photoIdFront = await Util.readFile('./path/to/image/front');
> var photoIdBack = await Util.readFile('./path/to/image/back');
>
> var sep9Files = {
>   'photo_id_front': photoIdFront,
>   'photo_id_back': photoIdBack,
> };
>
> await sep12.add(sep9Info, sep9Files: sep9Files);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let sep12 = try await anchor.sep12(authToken: authToken)
>
> let sep9Info = [
>     "first_name" : "john",
>     "last_name" : "smith",
>     "email_address" : "123@gmail.com",
>     "bank_number" : "12345",
>     "bank_account_number" : "12345",
> ]
>
> let photoIdFront:Data = // ...
> let photoIdBack:Data = // ...
>
> let sep9Files = [
>   "photo_id_front": photoIdFront,
>   "photo_id_back": photoIdBack,
> ]
>
> let addResponse = try await sep12.add(sep9Info: sep9Info, sep9Files: sep9Files)
> ```

## Start a withdrawal

Starting a withdrawal is similar to deposit, and has the same response types as described earlier.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const resp = await sep6.withdraw({
>   authToken,
>   params: {
>     asset_code: "SRT",
>     account: accountKp.publicKey,
>     type: "bank_account",
>     dest: "123",
>     dest_extra: "12345",
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var params = Sep6WithdrawParams(
>     assetCode: 'SRT',
>     account: accountId,
>     type: 'bank_account',
>     dest: '123',
>     destExtra: '12345',
> );
>
> var resp = await anchor.sep6().withdraw(params, authToken);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let params = Sep6WithdrawParams(
>   assetCode: "SRT",
>   account: accountId,
>   type: "bank_account",
>   dest: "123",
>   destExtra: "12345")
>
> let resp = try await anchor.sep6.withdraw(params: withdrawParams,
>                                           authToken: authToken)
> ```

## Get exchange info

If the anchor supports [SEP-38] quotes, it can support deposits that make a bridge between non-equivalent assets. For example, an anchor recieves BRL via bank transfer and in return sends USDC (of equivalent value minus fees) to the user on Stellar.

The sep6 exchange functions allow a user to start an exchange deposit or withdrawal with the anchor, and the anchor can communicate back next steps to the user.

First, let's start a deposit exchange with sample data. Assets are described using the [SEP-38] scheme.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const resp = await sep6.depositExchange({
>   authToken,
>   params: {
>     destination_asset:
>       "stellar:SRT:GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B",
>     source_asset: "iso4217:USD",
>     amount: "10",
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var params = Sep6DepositExchangeParams(
>     destinationAssetCode: 'SRT',
>     sourceAssetId: FiatAssetId('USD'),
>     amount: '10',
> );
>
> var resp = await anchor.sep6().depositExchange(params, authToken);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let params = Sep6DepositExchangeParams(
>   destinationAssetCode: "SRT",
>   sourceAssetId: FiatAssetId(id: "USD"),
>   amount: "10")
>
> let resp = try await anchor.sep6.depositExchange(params: params,
>                                                  authToken: authToken)
> ```

The response follows the same types as all the deposits and withdrawals for SEP-6.

Now let's create a withdrawal exchange, which follows the same format as the deposit exchange. We also specify it's a bank account withdrawal using the `type` field.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const resp = await sep6.withdrawExchange({
>   authToken,
>   params: {
>     destination_asset: "iso4217:USD",
>     source_asset:
>       "stellar:SRT:GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B",
>     amount: "10",
>     type: "bank_account",
>   },
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var params = Sep6WithdrawExchangeParams(
>     sourceAssetCode: 'SRT',
>     destinationAssetId: FiatAssetId('USD'),
>     amount: '10',
>     type: 'bank_account',
> );
>
> var resp = await anchor.sep6().withdrawExchange(params, authToken);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let params = Sep6WithdrawExchangeParams(
>   sourceAssetCode: "SRT",
>   destinationAssetId: FiatAssetId("USD"),
>   amount: "10",
>   type: "bank_account")
>
> let resp = try await anchor.sep6.withdrawExchange(params: params,
>                                                   authToken: authToken)
> ```

The response follows the same types as all the deposits and withdrawals for SEP-6.

## Getting Transaction Info

On the typical flow, the wallet would get transaction data to notify users about status updates. This is done via the [SEP-6] `GET /transaction` and `GET /transactions` endpoint.

### Tracking Transaction

Let's look into how to use the sdk to track transaction status changes. We will use the `Watcher` class for this purpose. First, let's initialize it and start tracking a transaction.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const watcher = anchor.sep6().watcher();
>
> const { stop, refresh } = watcher.watchOneTransaction({
>   authToken,
>   assetCode,
>   id: txId,
>   onSuccess,
>   onMessage,
>   onError,
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var watcher = anchor.sep6.watcher();
> var result = watcher.watchOneTransaction(authToken, 'transaction id');
>
> result.controller.stream.listen(
>   (event) {
>     if (event is StatusChange) {
>       print('Status changed to ${event.status}. Transaction: ${event.transaction.id}');
>     } else if (event is ExceptionHandlerExit) {
>       print('Exception handler exited the job');
>     } else if (event is StreamControllerClosed) {
>       print('Stream controller closed. Job is done');
>     }
>   }
> );
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let watcher = anchor.sep6.watcher()
> let result = watcher.watchOneTransaction(authToken: token,
>                                          id: "transaction id")
>
> NotificationCenter.default.addObserver(self,
>                                        selector: #selector(handleEvent(_:)),
>                                        name: result.notificationName,
>                                        object: nil)
>
> /// ...
> @objc public func handleEvent(_ notification: Notification) {
>     if let statusChange = notification.object as? StatusChange {
>         print("Status change to \(statusChange.status.rawValue). Transaction: \(statusChange.transaction.id)")
>     } else if let _ = notification.object as? ExceptionHandlerExit {
>         print("Exception handler exited the job")
>     } else if let _ = notification.object as? NotificationsClosed {
>         print("Notifications closed. Job is done")
>     }
> }
> ```

Alternatively, we can track multiple transactions for the same asset.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const watcher = anchor.sep6().watcher();
>
> const { stop, refresh } = watcher.watchAllTransactions({
>   authToken,
>   assetCode,
>   onMessage,
>   onError,
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var watcher = anchor.sep6.watcher();
> var result = watcher.watchAsset(authToken, asset);
>
> result.controller.stream.listen(
>   (event) {
>     if (event is StatusChange) {
>       print('Status changed to ${event.status}. Transaction: ${event.transaction.id}');
>     } else if (event is ExceptionHandlerExit) {
>       print('Exception handler exited the job');
>     } else if (event is StreamControllerClosed) {
>       print('Stream controller closed. Job is done');
>     }
>   }
> );
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let watcher = anchor.sep6.watcher()
> let result = watcher.watchAsset(authToken: token,
>                                 asset: asset)
>
> NotificationCenter.default.addObserver(self,
>                                        selector: #selector(handleEvent(_:)),
>                                        name: result.notificationName,
>                                        object: nil)
>
> /// ...
> @objc public func handleEvent(_ notification: Notification) {
>     if let statusChange = notification.object as? StatusChange {
>         print("Status change to \(statusChange.status.rawValue). Transaction: \(statusChange.transaction.id)")
>     } else if let _ = notification.object as? ExceptionHandlerExit {
>         print("Exception handler exited the job")
>     } else if let _ = notification.object as? NotificationsClosed {
>         print("Notifications closed. Job is done")
>     }
> }
> ```

### Fetching Transaction

While `Watcher` class offers powerful tracking capabilities, sometimes it's required to just fetch a transaction (or transactions) once. The `Anchor` class allows you to fetch a transaction by ID, Stellar transaction ID, or external transaction ID:

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const transaction = await anchor
>   .sep6()
>   .getTransactionBy({ authToken, id: transactionId });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var transaction = await anchor.sep6().getTransactionBy(
>     authToken: authToken,
>     id: transactionId,
> );
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let transaction = try await anchor.sep6.getTransactionBy(
>   authToken: authToken,
>   transactionId:transactionId)
> ```

It's also possible to fetch transactions by the asset.

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const transactions = await anchor.sep6().getTransactionsForAsset({
>   authToken,
>   assetCode,
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> var transactions = await anchor.sep6().getTransactionsForAsset(
>   authToken: authToken,
>   assetCode: assetCode,
> );
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let transactions = try await anchor.sep6.getTransactionsForAsset(
>   authToken: authToken,
>   assetCode: assetCode)
>
> ```

[sep-6]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md

[sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md

[sep-10]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md

[sep-12]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md

[sep-38]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0038.md

[stellar authentication]: https://developers.stellar.org/docs/build/apps/wallet/sep10.md
