Skip to content

Commit

Permalink
SEP-6: Accept financial information via SEP-12 (#1380)
Browse files Browse the repository at this point in the history
### Abstract
Today, wallets are required to send a user's financial account
information mainly through the `dest` and `dest_extra` request
parameters when requesting a withdrawal. This is a security risk
as web servers often log their GET requests which will include
personally identifiable information such as a user's bank account
number. The standard should define an alternative method for
allowing users to provide their information.

### Proposal
This PR proposes excluding the `fields` from the withdrawal types
returned by the `GET /info` endpoint as a means to collect these
fields through an alternative flow. This will force the anchor to
put the transaction into the `pending_customer_info_update` status.
The wallet will use then SEP-12 `PUT /customer` to provide the
missing financial account information. This allows us to deprecate
the `dest` and `dest_extra` request parameters by making them
optional when a withdraw type's `fields` object is missing.

### Backwards Compatibility
This change is backward compatible as wallets will continue sending
financial account information through the request parameters if the
anchors define them as part of the `GET /info` response.

This depends on some changes from
#1379.
  • Loading branch information
philipliu authored Aug 30, 2023
1 parent d0ef9fb commit 142afff
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions ecosystem/sep-0006.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Author: SDF
Status: Active (Interactive components are deprecated in favor of SEP-24)
Created: 2017-10-30
Updated: 2023-08-15
Version 3.20.0
Version 3.21.0
```

## Simple Summary
Expand Down Expand Up @@ -158,7 +158,7 @@ This protocol involves the transfer of value, and so HTTPS is required for all e

## Callback signature

This protocol involves the optional use of callbacks that the Anchor can issue to update the wallet on `status` of a transaction. In order to validate the integrity and provenance of the callback, the Anchor MUST include a signature in the HTTP Header `Signature` or `X-Stellar-Signature` (deprecated).
This protocol involves the optional use of callbacks that the Anchor can issue to update the wallet on `status` of a transaction. In order to validate the integrity and provenance of the callback, the Anchor MUST include a signature in the HTTP Header `Signature` or `X-Stellar-Signature` (**Deprecated**).

Wallets should support both headers until the `X-Stellar-Signature` header is removed from the specification.

Expand All @@ -173,7 +173,7 @@ It is the wallet's responsibility to:

### VERIFY signature

* Check that callback request has `Signature` or `X-Stellar-Signature` (deprecated) header
* Check that callback request has `Signature` or `X-Stellar-Signature` (**Deprecated**) header
* Parse the header and extract:
* Key `t`: __timestamp__
* Key `s`: __base64 signature__
Expand All @@ -199,7 +199,7 @@ It is the wallet's responsibility to:
* The callback request body
* Sign the payload `<timestamp>.<host>.<body>` using the Anchor private key
* Base64 encode the signature
* Build the `Signature` or `X-Stellar-Signature` (deprecated) header:
* Build the `Signature` or `X-Stellar-Signature` (**Deprecated**) header:
* `Signature: t=<current timestamp>, s=<base64 encoded signature>`
* `X-Stellar-Signature: t=<current timestamp>, s=<base64 encoded signature>`

Expand Down Expand Up @@ -268,18 +268,16 @@ SEP-6 lays out many options for how deposit and withdrawal can work. These are r
* Provide an interface that allows users to pick an asset, anchor, and amount to use for deposit or withdraw. The interface should display the asset's fee structure (if possible) as well as information such as the address of the anchor and description of the asset from the `stellar.toml` file.
* **Use the `/info` endpoint**
* Determine which anchor endpoints will require authentication
* Fetch the asset's deposit & withdawal fee structure: if `fee_fixed` and `fee_percent` are provided, show this to the user early in the process so they're fully informed.
* Fetch the asset's deposit & withdrawal fee structure: if `fee_fixed` and `fee_percent` are provided, show this to the user early in the process so they're fully informed.
* If the `/fee` endpoint is enabled, use it for computing fees when you need to show them to the user.
* While `/info` allows an anchor to communicate non-standard fields that are needed for `/deposit` or `/withdraw`, it's easier for a basic wallet implementation to hard-code extra fields that are needed on a per-anchor basis, and ensure those fields are passed in properly.
* While `/info` allows an anchor to communicate fields that are needed for `/deposit` or `/withdraw`, Anchors are recommended not to collect these through request parameters, but rather through [SEP-12](sep-0012.md) to avoid leaking sensitive information through URLs. If the anchor requires fields to be provided through request parameters, the wallet can hard-code any extra fields on a per-anchor basis to ensure those fields are passed in correctly.
* **Authentication**
* If needed, perform [authentication](#authentication) via SEP-10 before hitting those endpoints
* **Make a request to `/deposit` or `/withdraw`.**
* As a conservative measure, pass in any optional fields (including amount) that the wallet has on-hand, such as `email_address` and `account`.
* In the `/withdraw` request, have the user enter the crypto account or bank account where they'd like their withdrawal to end up and provide that to the anchor via `dest` and `dest_extra`.
* Before making the payment, make a request to `[SEP-6]/transaction?id=<transaction_id>` to get the amount_in details. Some anchors may use additive fees, which would produce an `amount_in` different from the wallet's proposed amount.
* **For `/deposit`**
* If the anchor's `/deposit` endpoint immediately returns success:
* display the deposit info that came back from the endpoint to the user, including fee. You're done! The user will execute the deposit exernally using the instructions if they want to.
* display the deposit info that came back from the endpoint to the user, including fee. You're done! The user will execute the deposit externally using the instructions if they want to.
* Handle the [special cases](#special-cases), they're relatively common.
* **For `/withdraw`**
* If the anchor's `/withdraw` endpoint immediately returns success:
Expand All @@ -290,7 +288,7 @@ SEP-6 lays out many options for how deposit and withdrawal can work. These are r

### Basic Anchor Implementation

* Provide a full-featured implementation of [`/info`](#info).
* Provide a full-featured implementation of [`/info`](#info) using SEP-12 to collect any KYC or financial account information from the user.
* Decide which endpoints, if any, need to be [authenticated](#authentication), and declare that properly in the `/info` endpoint.
* Pick your approach to [fees](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md#fee). We recommend using `/info` to express fees as it provides a better user experience (the user can see the fee structure in the wallet early in the process).
* **For both deposit and withdrawal**:
Expand Down Expand Up @@ -567,11 +565,11 @@ Name | Type | Description
-----|------|------------
`asset_code` | string | Code of the on-chain asset the user wants to withdraw. The value passed must match one of the codes listed in the [/info](#info) response's withdraw object.
`type` | string | Type of withdrawal. Can be: `crypto`, `bank_account`, `cash`, `mobile`, `bill_payment` or other custom values. This field may be necessary for the anchor to determine what KYC information is necessary to collect.
`dest` | string | The account that the user wants to withdraw their funds to. This can be a crypto account, a bank account number, IBAN, mobile number, or email address.
`dest_extra` | string | (optional) Extra information to specify withdrawal location. For crypto it may be a memo in addition to the `dest` address. It can also be a routing number for a bank, a BIC, or the name of a partner handling the withdrawal.
`dest` | string | (**Deprecated**, [see note below](#dest--dest_extra-parameters)) The account that the user wants to withdraw their funds to. This can be a crypto account, a bank account number, IBAN, mobile number, or email address.
`dest_extra` | string | (**Deprecated**, [see note below](#dest--dest_extra-parameters), optional) Extra information to specify withdrawal location. For crypto it may be a memo in addition to the `dest` address. It can also be a routing number for a bank, a BIC, or the name of a partner handling the withdrawal.
`account` | `G...` or `M...` string | (optional) The Stellar or muxed account the client will use as the source of the withdrawal payment to the anchor. If SEP-10 authentication is not used, the anchor can use `account` to look up the user's KYC information. Note that the account specified in this request could differ from the account authenticated via SEP-10.
`memo` | string | (optional) This field should only be used if SEP-10 authentication is not. It was originally intended to distinguish users of the same Stellar account. However if SEP-10 is supported, the anchor should use the `sub` value included in the decoded SEP-10 JWT instead. See the [Shared Account Authentication](#shared-omnibus-or-pooled-accounts) section for more information.
`memo_type` | string | (**deprecated**, optional) Type of `memo`. One of `text`, `id` or `hash`. Deprecated because memos used to identify users of the same Stellar account should always be of type of `id`.
`memo_type` | string | (**Deprecated**, optional) Type of `memo`. One of `text`, `id` or `hash`. Deprecated because memos used to identify users of the same Stellar account should always be of type of `id`.
`wallet_name` | string | (optional) In communications / pages about the withdrawal, anchor should display the wallet name to the user to explain where funds are coming from.
`wallet_url` | string | (optional) Anchor can show this to the user when referencing the wallet involved in the withdrawal (ex. in the anchor's transaction history).
`lang` | string | (optional) Defaults to `en` if not specified or if the specified language is not supported. Language code specified using [RFC 4646]. `error` fields and other human readable messages in the response should be in this language.
Expand All @@ -583,6 +581,12 @@ Name | Type | Description

The request parameters also must include the required fields from the `/info` endpoint.

##### `dest` & `dest_extra` parameters:

These have been deprecated as sending personally identifiable information through request parameters is a security risk due to web server request logging.

Financial account information should be sent via the [SEP-12](sep-0012.md#customer-put). To maintain backwards compatibility with Anchors expecting these fields, these parameters should be set only if the withdrawal type fields include `dest` and/or `dest_extra` in the `/info` response.

Example:

```
Expand Down Expand Up @@ -695,11 +699,11 @@ Name | Type | Description
`quote_id` | string | (optional) The `id` returned from a `SEP-38 POST /quote` response. If this parameter is provided and the Stellar transaction used to send the asset to the Anchor has a [`created_at`](https://developers.stellar.org/api/resources/transactions/object/) timestamp earlier than the quote's `expires_at` attribute, the Anchor should respect the conversion rate agreed in that quote. If the values of `destination_asset`, `source_asset` and `amount` conflict with the ones used to create the [SEP-38] quote, this request should be rejected with a `400`.
`amount` | string | The amount of the on-chain asset (`source_asset`) the user would like to send to the anchor's Stellar account. This field may be necessary for the anchor to determine what KYC information is necessary to collect. Should be equals to `quote.sell_amount` if a `quote_id` was used.
`type` | string | Type of withdrawal. Can be: `crypto`, `bank_account`, `cash`, `mobile`, `bill_payment` or other custom values. This field may be necessary for the anchor to determine what KYC information is necessary to collect.
`dest` | string | The account that the user wants to withdraw their funds to. This can be a crypto account, a bank account number, IBAN, mobile number, or email address.
`dest_extra` | string | (optional) Extra information to specify withdrawal location. For crypto it may be a memo in addition to the `dest` address. It can also be a routing number for a bank, a BIC, or the name of a partner handling the withdrawal.
`dest` | string | (**Deprecated**, [see note](#dest--dest_extra-parameters)) The account that the user wants to withdraw their funds to. This can be a crypto account, a bank account number, IBAN, mobile number, or email address.
`dest_extra` | string | (**Deprecated**, [see note](#dest--dest_extra-parameters), optional) Extra information to specify withdrawal location. For crypto it may be a memo in addition to the `dest` address. It can also be a routing number for a bank, a BIC, or the name of a partner handling the withdrawal.
`account` | `G...` or `M...` string | (optional) The Stellar or muxed account of the user that wants to do the withdrawal. This is only needed if the anchor requires KYC information for withdrawal and SEP-10 authentication is not used. Instead, the anchor can use `account` to look up the user's KYC information. Note that the account specified in this request could differ from the account authenticated via SEP-10.
`memo` | string | (optional) This field should only be used if SEP-10 authentication is not. It was originally intended to distinguish users of the same Stellar account. However if SEP-10 is supported, the anchor should use the `sub` value included in the decoded SEP-10 JWT instead. See the [Shared Account Authentication](#shared-omnibus-or-pooled-accounts) section for more information.
`memo_type` | string | (**deprecated**, optional) Type of `memo`. One of `text`, `id` or `hash`. Deprecated because memos used to identify users of the same Stellar account should always be of type of `id`.
`memo_type` | string | (**Deprecated**, optional) Type of `memo`. One of `text`, `id` or `hash`. Deprecated because memos used to identify users of the same Stellar account should always be of type of `id`.
`wallet_name` | string | (optional) In communications / pages about the withdrawal, anchor should display the wallet name to the user to explain where funds are coming from.
`wallet_url` | string | (optional) Anchor can show this to the user when referencing the wallet involved in the withdrawal (ex. in the anchor's transaction history).
`lang` | string | (optional) Defaults to `en` if not specified or if the specified language is not supported. Language code specified using [RFC 4646]. `error` fields and other human readable messages in the response should be in this language.
Expand Down Expand Up @@ -1010,7 +1014,7 @@ All assets listed in a `withdraw` and `withdraw-exchange` can contain these attr

* `enabled`: `true` if SEP-6 withdrawal for this asset is supported
* `authentication_required`: Optional. `true` if client must be [authenticated](#authentication) before accessing the withdraw endpoint for this asset. `false` if not specified.
* `types`: a field with each type of withdrawal supported for that asset as a key. Each type can specify a `fields` object as below explaining what fields are needed and what they do.
* `types`: a field with each type of withdrawal supported for that asset as a key. Each type can specify a `fields` object as below explaining what fields are needed and what they do. Anchors are encouraged to use [SEP-9 financial account fields](sep-0009.md#financial-account-fields), but can also define custom fields if necessary. If a `fields` object is not specified, the wallet should assume that no extra fields are needed for that type of withdrawal. In the case that the Anchor requires additional fields for a withdrawal, it should set the transaction status to `pending_customer_info_update`. The wallet can query the `/transaction` endpoint to get the fields needed to complete the transaction in `required_customer_info_updates` and then use [SEP-12](sep-0012.md#customer-put) to collect the information from the user.

Withdrawal assets listed in the `withdraw` object can also contain the attributes:

Expand Down Expand Up @@ -1174,7 +1178,7 @@ Name | Type | Description
`refunded` | boolean | (**deprecated**, optional) This field is deprecated in favor of the `refunds` object. True if the transaction was refunded in full. False if the transaction was partially refunded or not refunded. For more details about any refunds, see the `refunds` object.
`refunds` | object | (optional) An object describing any on or off-chain refund associated with this transaction. The schema for this object is defined in the [Refunds Object Schema](#refunds-object-schema) section below.
`required_info_message` | string | (optional) A human-readable message indicating any errors that require updated information from the user.
`required_info_updates` | object | (optional) A set of fields that require update from the user described in the same format as [/info](#info). This field is only relevant when `status` is `pending_transaction_info_update`.
`required_info_updates` | object | (optional) A set of fields that require update from the user described in the same format as [/info](#info). This field is only relevant when `status` is `pending_transaction_info_update`.
`required_customer_info_message` | string | (optional) A human-readable message indicating why the SEP-12 information provided by the user is not sufficient to complete the transaction.
`required_customer_info_updates` | string | (optional) A set of SEP-9 fields that require update from the user via SEP-12. This field is only relevant when `status` is `pending_customer_info_update`.
`instructions` | string | (optional) JSON object containing the [SEP-9 financial account fields](sep-0009.md#financial-account-fields) that describe how to complete the off-chain deposit in the same format as the [/deposit](#deposit) response. This field should be present if the `instructions` were provided in the [/deposit](#deposit) response or if it could not have been previously provided synchronously. This field should only be present once the status becomes `pending_user_transfer_start`, not while the transaction has any statuses that precede it such as `incomplete`, `pending_anchor`, or `pending_customer_info_update`.
Expand Down Expand Up @@ -1430,7 +1434,7 @@ Another possibility is that information described in the anchor's `/info` `field
PATCH TRANSFER_SERVER/transactions/:id
```

This endpoint should only be used when the anchor requests more info via the `pending_transaction_info_update` status. The `required_info_updates` transaction field should contain the fields required for the update. If the sender tries to update at a time when no info is requested the receiver should fail with an error response.
This endpoint should only be used when the anchor requests more info via the `pending_transaction_info_update` status. The `required_info_updates` transaction field should contain the fields required for the update. If the wallet tries to update at a time when no info is requested, the anchor should reject the update and return a 400 error.

Name | Type | Description
-----|------|------------
Expand Down Expand Up @@ -1477,6 +1481,7 @@ If the information was malformed, or if the sender tried to update data that isn

## Changelog

* `v3.21.0`: Accept financial information via SEP-12. ([#1379](https://github.com/stellar/stellar-protocol/pull/1380/))
* `v3.20.0`: Add support for asynchronous deposit instructions. ([#1379](https://github.com/stellar/stellar-protocol/pull/1379/))
* `v3.19.0`: Deprecate `/fee` endpoint.([#1381](https://github.com/stellar/stellar-protocol/pull/1381))
* `v3.18.1`: Fix the missing types of the `withdraw` request parameters and some typo. ([#1365](https://github.com/stellar/stellar-protocol/pull/1365))
Expand Down

0 comments on commit 142afff

Please sign in to comment.