Skip to main content
Version: 2.9

Set Up a Production Server

Once the test server is live and you have tested both deposit and withdraw flows, it's time to get started with the real deploy connected to real KYC and real banking rails providers. Before using any banking APIs, it's critical that you perform a full security audit on the system to make sure that there aren't any vulnerabilities.

Deploying a Secure Environment

Make sure to keep the test server up, and deploy the production (mainnet) system in a separate environment. Having two deploys allows you to validate new features on the testnet before moving them to the final production deploy. You can also have a third staging environment if there's a big team working on this codebase and/or there will be many pushes to be tested internally before sharing with other institutions.

To switch to Stellar's public (mainnet) network, all you have to do is change the network passphrase (for authenticating requests) and Horizon URL.

You can copy your existing development configs to create a production configuration.

First, you need to change your info file (stellar.toml):

# stellar.toml
NETWORK_PASSPHRASE = "Public Global Stellar Network ; September 2015"

Next, change your Anchor Platform configuration in production.env file:

# production.env
STELLAR_NETWORK_NETWORK="Public"
STELLAR_NETWORK_HORIZON_URL=https://horizon.stellar.org

Connecting to Real KYC

Most anchors need to collect Know Your Customer information to comply with local regulations before honoring deposits and withdrawals. The KYC flow usually consists of a simple form that gathers relevant information about the user such as name, email, address, age, and government-issued ID number.

How you handle KYC is up to you: there are many services that provide KYC solutions through APIs and iFrames, and validate the input data and sync with governmental databases to verify requirements. Each jurisdiction has specific KYC requirements, and they differ from jurisdiction to jurisdiction, so it's best to find a country-specific KYC provider that meets your needs.

Some countries require different KYC fields depending on the amount to be deposited or withdrawn. If that's the case in your jurisdiction and you need to adapt your KYC forms based on the deposit or withdrawal amount, simply add an amount field before the KYC form, and make sure that the KYC fields are updated based on that value.

KYC information should be linked to the session created through Stellar Web Authentication and, consequently, to the user, so you only need to ask the user for it once. After the first KYC flow is complete, a user shouldn't have to input the information again.

Make sure the errors and validation messages are clear and include instructions for what to do next to ensure a good user experience and increase the KYC conversion rate. You should also localize messages based on the user's language and location.

Pre-Filling the KYC Form

Pre-filling the KYC form is a great way to reduce the friction of getting started using an anchor, and wallets usually provide a set of fields that are commonly used throughout the ecosystem. In summary, the anchor can render the KYC form with the user's values that were previously sent by the wallet in the /transactions/deposit/interactive and /transactions/withdraw/interactive endpoints.

All fields from SEP-9 can be sent by wallets in the previously mentioned endpoints, but the most common are: email, first name, last name and phone number. Also, you should still enable the pre-filled fields to be editable, since the user might have inputted a different name in the Wallet's sign-up process, and could want to edit it before finalizing the Anchor's KYC process.

All SEP-9 data that was sent from the wallet is a part of the Interactive JWT, send by the Anchor Platform

Connecting to Real Banking Rails

Fiat-backed token issuers are expected to manage a full reserve. That means there's a 1:1 relationship between Stellar-network tokens and money in the bank. Since each fiat token on Stellar is backed by, and can be redeemed for, an underlying, real-world asset, issuers of fiat-backed tokens need to connect to real banking rails to validate user deposits (through bank transfers, credit card payments, etc.) and to complete user withdrawals (generally through bank transfers). If you're an anchor honoring deposits and withdrawals of a token another organization issues, you'll follow a similar process.

In order to fetch (and identify) a user transfer, issuers usually take one of two approaches:

  • API Polling: this option consists of fetching the bank's API, through a cron job, to check for the updated status of the list of transfers received by (and sent from) the issuer's bank account. Once the system confirms a new transaction and identifies that it relates to a specific deposit, it can send the digital funds to that user's account
  • Webhook: not all banking rails support this option, but it's the leanest in terms of back-end logic. In this approach, the bank proactively hits an issuer's endpoint once it receives a new transfer, updating that information on the issuer's database. The issuer can then can match that transaction to an existing in-process deposit, and validate that the user can receive their digital funds

There are many ways to identify that a specific bank transfer relates to a specific deposit (and, consequently, to a user). Some banks (and countries) have transfer infrastructure that allows the creation of a single bank account per transfer; others require users to add an identification parameter to their transfers. Some banks provide the user ID number in the transaction information so issuers can match that with the information provided in the KYC form.

Make sure to do a full security audit on your systems when banking rails connections are in place. Some banks provide a testing API that can be used for development and deployment to testnet or staging environments, which means you can test and audit the codebase before moving to a final production-ready bank integration. For better security, some anchors also prefer to add a manual final step before approving withdrawal transfers. In terms of UX, this manual approval is acceptable as long as the wait times align with user expectations, which usually means they aren't longer than a couple of hours.

Testing Edge Cases

Once your application is fully functional, it's a good idea to test different scenarios and edge cases to make sure the system is behaving as expected. Here's a list of testing suggestions that should cover a large amount of the application's edge cases:

General Tests

  • Test the interactive flow usability
  • Test the interface using different locale information, and check for translated content including error messages, responses, date formatting, and number formatting

KYC Tests

  • Check that KYC appears with a new wallet SK
  • Check that KYC doesn't accept incorrectly formatted inputs, and that the error messages are comprehensible
  • Check that you can use the same KYC information (email, phone number, username, etc) multiple times
  • Check that you can go through KYC multiple times with the same Stellar SK.

Interactive Test

  • Check that the deposit flow goes through, and that the banking rails are working
  • Check that you cannot make a withdrawal with a value higher than the current balance
  • Check that the withdrawal flow goes through, and that the banking rails are working

Security Tests

  • Make sure platform endpoints are secured

Polishing and Internationalization

Supporting two languages (English and the fiat currency country language) allows users to have a seamless experience while navigating through screens, and supports international institutions (like wallets) that need to test the product before starting new integrations.

You can support multiple languages in your webapp by using the Accept-Language parameter from the http request headers to localize the content and allowing users to change that in a simple way (e.g. a flag icon on the top bar). If a specific wallet doesn't send the header parameter, we recommend showing the user a language selection screen in the beginning of the deposit and withdraw processes. Once a user chooses a language, you can store their selection so you only need to ask them once. In addition to localizing text, make sure to check number formatting, dates, etc.

Having a group of beta testers is a great way to check if there are any edge cases that need polishing, and to confirm that the system is working well with a variety of user inputs. You can beta test using a soft launch stage before you start putting effort into marketing and distribution. Documenting the testing process with screenshots and videos is very helpful for future security audits, and gives new partners and potential users clarity and confidence in the product.

Connecting to Wallets

All Anchor user interactions are done through a Wallet, so it's vital for Anchors to be connected to Wallets that have a good market penetration in the region where the business is most focused. Connecting to Wallets is a simple process, since both ends of that integration are already compliant with SEPs.

Stellar.org maintains a list of wallets, many of which currently support SEP-24 Sending them a message with more information on an asset and an issuer account is a great way to start getting some real users to the Anchor.