Skip to main content
Version: 3.0.0

Configuration

Modify a Stellar Info File

Let's start by modifying our stellar.toml file created earlier. Wallets need to know that SEP-31 functionality is supported by your business, and they also need to know all currencies you support.

# dev.stellar.toml
ACCOUNTS = ["add your public keys for your distribution accounts here"]
SIGNING_KEY = "add your signing key here"
NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"

DIRECT_PAYMENT_SERVER = "http://localhost:8080/sep31"
WEB_AUTH_ENDPOINT = "http://localhost:8080/auth"

[[CURRENCIES]]
code = "USDC"
issuer = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5"
status = "test"
is_asset_anchored = false
desc = "USD Coin issued by Circle"

[DOCUMENTATION]
ORG_NAME = "Your organization"
ORG_URL = "Your website"
ORG_DESCRIPTION = "A description of your organization"

Note that you'll need to create another file for your production deployment that uses the public network's passphrase, your production service URLs, your mainnet distribution accounts and signing key, as well as the mainnet issuing accounts of the assets your service utilizes.

Enable Cross Border Payments

Now you're ready to enable cross-border payments the SEP-31 API. Specify the following in your dev.assets.yaml file.

# dev.assets.yaml
assets:
- schema: stellar
code: USDC
issuer: GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5
distribution_account: GBLSAHONJRODSFTLOV225NZR4LHICH63RIFQTQN37L5CRTR2IMQ5UEK7
significant_decimals: 2
sep31_enabled: true
sep31:
quotes_supported: true
quotes_required: true
fields:
transaction: {}
send:
min_amount: 0
max_amount: 10000

The information provided in the sep31 and send objects closely map to the information that will be exposed to the wallet application using the GET /info SEP-31 endpoint. The Anchor Platform also uses this information to validate requests made to your service. sep31.fields.transaction should be left empty and will be removed in a future release, but you can adjust the send.min_amount and send.max_amount values according to your service's limits.

The sep31.quotes_supported and sep31.quotes_required determine whether or not sending organizations can and are required to request an FX rate using the SEP-38 POST /quote endpoint. Almost all senders prefer this approach so that they can communicate the rate to their customers prior to proceeding.

Add the following variable to your environment file.

# dev.env
SEP31_ENABLED=true

Senders should now be able to discover, authenticate, and initiate transactions with your service! Run the following command to start the Anchor Platform.

docker compose up

Check that your API is live.

curl http://localhost:8080/sep31/info | jq

You should get the following.

{
"receive": {
"USDC": {
"enabled": true,
"quotes_supported": true,
"quotes_required": true,
"min_amount": 0,
"max_amount": 10000,
"fields": {
"transaction": {}
}
}
}
}

Enable the Customer KYC API

Businesses need to collect and validate KYC information on the customers they're facilitating transactions for. Clients determine what KYC information needs to be collected and send that information via a SEP-12 KYC API hosted by the Anchor Platform, but the Anchor Platform never stores personally-identifiable information (PII). Instead, it forwards requests from clients to the business server, and returns the business' responses back to the client, acting as a proxy server.

See the Anchor Platform KYC API specification for details on the endpoints that must be implemented on your business' server.

To make this API available to clients, lets add the service URL to our Stellar Info File.

# dev.stellar.toml
KYC_SERVER = "http://localhost:8080/sep12"

Lets enable it in our environment too.

# dev.env
SEP12_ENABLED=true

Finally, we have to define your business' customer types. Each type of customer requires different a set of KYC information. For example, you can offer your cross-border payments service in two distinct regulatory jurisdictions, so customers in different jurisdictions have different KYC requirements and would be represented using different types.

info

Currently, customer types must be mutually exclusive, meaning a customer cannot be more than one type.

This limitation is in place because the Anchor Platform cannot validate whether a customer is approved for a specific type of transaction, such as one sending a large amount. It can only validate that a customer is approved for one of the customer types defined. This limitation will be removed in a future release.

In this guide, we'll only have two types, a sending customer type and a receiving customer type. Currently, our customer types are defined in our assets configuration, but this will change in a future release.

# dev.assets.yaml
sep31:
sep12:
sender:
types:
sep31-sender:
description: customers sending to recipients
receiver:
types:
sep31-receiver:
description: customers receiving from senders

Let's ping the info endpoint again to verify. After docker compose up, run the following command:

curl http://localhost:8080/sep31/info | jq

You should get the following:

{
"receive": {
"USDC": {
"enabled": true,
"quotes_supported": true,
"quotes_required": true,
"min_amount": 0,
"max_amount": 10000,
"fields": {
"transaction": {}
},
"sep12": {
"sender": {
"types": {
"sep31-sender": {
"description": "customers sending to recipients"
}
}
},
"receiver": {
"types": {
"sep31-receiver": {
"description": "customers receiving from senders"
}
}
}
}
}
}
}

Enable the RFQ API

Businesses need to provide their send-side counterparts with a Rate API to check the exchange rates they're offering between the on-chain asset being used for settlement and the fiat asset being used to pay the recipient. If the rate is competitive, senders also need to be able to request a commitment to the rate currently being offered from business for a short period of time.

The Anchor Platform provides the SEP-38 RFQ API to senders for this purpose.

To make this API available to clients, lets add the service URL to our Stellar Info File.

# dev.stellar.toml
DIRECT_PAYMENT_SERVER = "http://localhost:8080/sep31"
WEB_AUTH_ENDPOINT = "http://localhost:8080/auth"
KYC_SERVER = "http://localhost:8080/sep12"
QUOTE_SERVER = "http://localhost:8080/sep38"

Lets enable it in our environment too.

# dev.env
SEP38_ENABLED=true

We also need to enable USDC to be used in this API, as well as add an off-chain asset it can be exchanged with.

# dev.assets.yaml
assets:
- schema: stellar
code: USDC
issuer: GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5
distribution_account: GBLSAHONJRODSFTLOV225NZR4LHICH63RIFQTQN37L5CRTR2IMQ5UEK7
significant_decimals: 2
sep31_enabled: true
sep38_enabled: true
send:
min_amount: 0
max_amount: 10000
sep31:
quotes_supported: true
quotes_required: true
fields:
transaction: {}
sep12:
sender:
types:
sep31-sender:
description: customers sending to recipients
receiver:
types:
sep31-receiver:
description: customers receiving from senders
sep38:
exchangeable_assets:
- iso4217:BRL
country_codes:
- BRA
- schema: iso4217
code: BRL
sep38_enabled: true
sep38:
exchangeable_assets:
- stellar:USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5
country_codes:
- BRA
significant_decimals: 2
buy_delivery_methods:
- name: PIX
description: Have BRL sent directly to your bank account.

Lets test that your RFQ API is live! Following docker compose up:

curl http://localhost:8080/sep38/info | jq

You should get the following:

{
"assets": [
{
"asset": "stellar:USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5"
},
{
"asset": "iso4217:BRL",
"country_codes": ["BRA"],
"buy_delivery_methods": [
{
"name": "PIX",
"description": "Have BRL sent directly to your bank account."
}
]
}
]
}

Configure Callback API Authentication

Just as your business will need to make requests to the Anchor Platform, the Anchor Platform will need to make requests to your business. Let's add authentication to these requests as well.

# dev.env
CALLBACK_API_BASE_URL=http://server:8081
CALLBACK_API_AUTH_TYPE=jwt
CALLBACK_API_AUTH_JWT_EXPIRATION_MILLISECONDS=30000
SECRET_CALLBACK_API_AUTH_SECRET=<your jwt encryption key>

CALLBACK_API_BASE_URL uses server instead of localhost as the host because the Anchor Platform will be making requests to your business server from within the local network created by docker compose. When configuring your service in a staging or production environment, make sure to update your service urls.

We'll define the server that implements the endpoints defined in the Callback API in the following section.