Backend service
Rafiki’s backend
service is the software’s main service for handling business logic and external communication. The service is responsible for:
- Exposing the endpoints of the Open Payments APIs for public clients to initiate payments and look up information. This is the external communication piece.
- Exposing an Interledger connector to send and receive STREAM packets with peers.
- Enabling you to manage accounts and track liquidity.
- Exposing an internal GraphQL Backend Admin API for service operators to manage accounts, liquidity, and application settings, like peering relationships.
Requirements
The following are required when using the backend
service.
- A Redis database as a cache to share STREAM connection details and total amounts received across processes
- A Postgres database, separate from the
auth
service’s database, for Open Payments resources - TigerBeetle or a separate Postgres database for accounting liquidity
You must also set the environment variables for the backend
service.
Open Payments
The backend
service exposes the Open Payments APIs, which are auth-protected using an opinionated version of the Grant Negotiation and Authorization Protocol (GNAP). Review the auth
service page for more details about grant authorization and authentication.
The backend
service allows you to manage Open Payments incoming payments, quotes, and outgoing payments. Quotes and outgoing payments call the ILP connector, described in the next section, to send ILP packets. Quoting sends unfulfillable probe packets, for example to determine a transaction’s cost before executing the payment. Outgoing payments send packets as part of executing the payment.
Interledger connector
The backend
service exposes an ILP connector to send and receive ILP packets between peers.
Some of the responsibilities of a connector include:
- Authenticating packets against ILP account credentials.
- Forwarding packets to a sender or receiver.
- Rejecting a packet for any number of reasons, including expiration, insufficient liquidity, rate limit exceeded, or if the amount exceeds the
maxPacketAmount
agreed to by the connector and its peer. - Converting currencies.
- Fulfilling packets with an internal STREAM server.
The backend
service includes an HTTP server listening on the configured CONNECTOR_PORT
. Your connector can receive incoming packets via HTTP and/or direct calls from within the backend
service. An incoming packet is only accepted if it’s from a configured peer and accompanied by your peer’s incoming HTTP authToken
.
Similarly, if a packet’s destination address corresponds to a peer, your connector will forward the packet to your peer over HTTP, along with your peer’s outgoing HTTP authToken
.
A packet can either continue on to your peer via HTTP or terminate at your Rafiki instance’s STREAM server. If the packet terminates at your STREAM server, your connector will attempt to extract and decode the payment tag from the packet’s destination address. When your connector successfully matches the tag with a locally managed wallet address or incoming payment, the connector will not forward the packet. Instead, it will credit the corresponding balance and track the total amount received in Redis to support STREAM receipts. Packets addressed to a wallet address happen via SPSP.
GraphQL Backend Admin API
The backend
service exposes a GraphQL Backend Admin API to manage assets, peers, wallet addresses, Open Payments resources, and several types of liquidity.
Environment variables
Variable | Helm Value Name | Default | Description |
---|---|---|---|
ADMIN_PORT | backend.port.admin | 3001 | Admin API GraphQL Server port |
AUTH_SERVER_GRANT_URL | undefined | endpoint on the Open Payments Auth Server to request a grant | |
AUTH_SERVER_INTROSPECTION_URL | undefined | endpoint on the Open Payments Auth Server to introspect an access token | |
AUTO_PEERING_SERVER_PORT | 3005 | If auto-peering is enabled, its server will use this port | |
CONNECTOR_PORT | backend.port.connector | 3002 | port of the ILP connector for for sending packets over ILP over HTTP |
DATABASE_URL | backend.postgresql.host, backend.postgresql.port, backend.postgresql.username, backend.postgresql.database, backend.postgresql.password | postgresql://postgres:password@localhost:5432/development | Postgres database URL of database storing the resource data; For Helm, these components are provided individually. |
ENABLE_AUTO_PEERING | false | Flag to enable auto peering. View documentation. | |
ENABLE_SPSP_PAYMENT_POINTERS | true | enables SPSP route | |
EXCHANGE_RATES_LIFETIME | backend.lifetime.exchangeRate | 15_000 | time in milliseconds the exchange rates provided by the ASE via the EXCHANGE_RATES_URL are valid for |
EXCHANGE_RATES_URL | backend.serviceUrls.EXCHANGE_RATES_URL | undefined | endpoint on the Account Servicing Entity to request exchange rates |
GRAPHQL_IDEMPOTENCY_KEY_TTL_MS | backend.idempotencyTTL | 86400000 | TTL in milliseconds for idempotencyKey on GraphQL mutations (Admin API). Default: 24hrs |
GRAPHQL_IDEMPOTENCY_KEY_LOCK_MS | 2000 | TTL in milliseconds for idempotencyKey concurrency lock on GraphQL mutations (Admin API) | |
ILP_ADDRESS | backend.ilp.address | undefined | ILP address of this Rafiki instance |
ILP_CONNECTOR_URL | undefined | The ILP connector address where ILP packets are received. Communicated during auto-peering | |
INCOMING_PAYMENT_EXPIRY_MAX_MS | 2592000000 | Maximum milliseconds into the future incoming payments expiry can be set to on creation. Default: 30 days | |
INCOMING_PAYMENT_WORKERS | backend.workers.incomingPayment | 1 | number of workers processing incoming payment requests |
INCOMING_PAYMENT_WORKER_IDLE | backend.workerIdle | 200 | time in milliseconds that INCOMING_PAYMENT_WORKERS will wait until they check an empty incoming payment request queue again |
INSTANCE_NAME | undefined | this Rafiki instance’s name used to communicate for auto-peering | |
KEY_ID | backend.key.id | undefined | this Rafiki instance’s client key id |
LOG_LEVEL | backend.logLevel | info | Pino Log Level |
NODE_ENV | backend.nodeEnv | development | node environment, development , test , or production |
OPEN_PAYMENTS_PORT | backend.port.openPayments | 3003 | port of the Open Payments resource server port |
OPEN_PAYMENTS_URL | backend.serviceUrls.OPEN_PAYMENTS_URL | undefined | public endpoint of this Open Payments Resource Server |
OUTGOING_PAYMENT_WORKERS | backend.workers.outgoingPayment | 4 | number of workers processing outgoing payment requests |
OUTGOING_PAYMENT_WORKER_IDLE | backend.workerIdle | 200 | time in milliseconds that OUTGOING_PAYMENT_WORKERS will wait until they check an empty outgoing payment request queue again |
PRIVATE_KEY_FILE | backend.key.file | undefined | the path to this Rafiki instance’s client private key |
QUOTE_LIFESPAN | backend.lifetime.quote | 5 * 60_000 | time in milliseconds an Open Payments quote is valid for |
REDIS_TLS_CA_FILE_PATH | backend.redis.tlsCaFile | '' | Redis TLS config |
REDIS_TLS_CERT_FILE_PATH | backend.redis.tlsCertFile | '' | Redis TLS config |
REDIS_TLS_KEY_FILE_PATH | backend.redis.tlsKeyFile | '' | Redis TLS config |
REDIS_URL | backend.redis.host, backend.redis.port | redis://127.0.0.1:6379 | Redis URL of database handling ILP packet data URL; For Helm, these components are provided individually. |
SIGNATURE_SECRET | backend.quoteSignatureSecret | undefined | secret to generate request header signatures for webhook event requests |
SIGNATURE_VERSION | 1 | version number to generate request header signatures for webhook event requests | |
SLIPPAGE | backend.ilp.slippage | 0.01 | accepted ILP rate fluctuation, default 1% |
STREAM_SECRET | backend.ilp.streamSecret | undefined | seed secret to generate shared STREAM secrets |
TIGERBEETLE_CLUSTER_ID | 0 | Tigerbeetle cluster ID picked by the system that starts the TigerBeetle cluster to create a Tigerbeetle client | |
TIGERBEETLE_REPLICA_ADDRESSES | 3004 | Tigerbeetle replica addresses for all replicas in the cluster, which are comma separated IP addresses/ports, to create a Tigerbeetle client | |
TRUST_PROXY | false | flag to use X-Forwarded-Proto header to determine if connections is secure | |
USE_TIGERBEETLE | true | flag - use TigerBeetle or Postgres for accounting | |
WALLET_ADDRESS_DEACTIVATION_PAYMENT_GRACE_PERIOD_MS | 86400000 | time in milliseconds into the future to set expiration of open incoming payments when deactivating wallet address. Default: 1 days | |
WALLET_ADDRESS_LOOKUP_TIMEOUT_MS | 1500 | time in milliseconds the ASE has to create a missing wallet address until timeout | |
WALLET_ADDRESS_POLLING_FREQUENCY_MS | 100 | frequency of polling while waiting for ASE to create a missing wallet address | |
WALLET_ADDRESS_URL | backend.serviceUrls.WALLET_ADDRESS_URL | http://127.0.0.1:3001/.well-known/pay | this Rafiki instance’s internal wallet address |
WALLET_ADDRESS_WORKERS | backend.workers.walletAddress | 1 | number of workers processing wallet address requests |
WALLET_ADDRESS_WORKER_IDLE | backend.workerIdle | 200 | time in milliseconds that WALLET_ADDRESS_WORKERS will wait until they check an empty wallet address request queue again |
WEBHOOK_MAX_RETRY | backend.webhookMaxRetry | 10 | maximum number of times Rafiki backend retries sending a certain webhook event to the configured WEBHOOK_URL |
WEBHOOK_TIMEOUT | backend.lifetime.webhook | 2000 | milliseconds |
WEBHOOK_URL | backend.serviceUrls.WEBHOOK_URL | undefined | endpoint on the Account Servicing Entity that consumes webhook events |
WEBHOOK_WORKERS | backend.workers.webhook | 1 | number of workers processing webhook events |
WEBHOOK_WORKER_IDLE | backend.workerIdle | 200 | time in milliseconds that WEBHOOK_WORKERS will wait until they check an empty webhook event queue again |
WITHDRAWAL_THROTTLE_DELAY | backend.withdrawalThrottleDelay | undefined | delay in liquidity withdrawal processing |
ENABLE_MANUAL_MIGRATIONS | backend.enableManualMigrations | false | When set to true, user needs to run database manually with command npm run knex -- migrate:latest --env production |