Skip to content
GitHub

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

Required

VariableHelm value nameDefaultDescription
AUTH_SERVER_GRANT_URLbackend.serviceUrls.AUTH_SERVER_GRANT_URLundefinedThe endpoint on your Open Payments authorization server to grant a request.
AUTH_SERVER_INTROSPECTION_URLbackend.serviceUrls.AUTH_SERVER_INTROSPECTION_URLundefinedThe endpoint on your Open Payments authorization server to introspect an access token.
DATABASE_URLbackend.postgresql.host,
backend.postgresql.port,
backend.postgresql.username,
backend.postgresql.database,
backend.postgresql.password
postgresql://postgres:password@localhost:5432/developmentThe Postgres database URL of the database storing your resource data. For Helm, these components are provided individually.
EXCHANGE_RATES_URLbackend.serviceUrls.EXCHANGE_RATES_URLundefinedThe endpoint your Rafiki instance uses to request exchange rates.
ILP_ADDRESSbackend.ilp.addressundefinedThe ILP address of your Rafiki instance.
ILP_CONNECTOR_URLbackend.ilp.connectorUrlundefinedThe ILP connector address where ILP packets are received.
KEY_IDbackend.key.idundefinedYour Rafiki instance’s client key ID.
OPEN_PAYMENTS_URLbackend.serviceUrls.OPEN_PAYMENTS_URLundefinedThe public endpoint of your Open Payments resource server.
REDIS_URLbackend.redis.host,
backend.redis.port
redis://127.0.0.1:6379The Redis URL of the database handling ILP packet data. For Helm, these components are provided individually.
USE_TIGERBEETLEbackend.use.tigerbeetletrueWhen true, a TigerBeetle database is used for accounting. When false, a Postgres database is used.
WEBHOOK_URLbackend.serviceUrls.WEBHOOK_URLundefinedYour endpoint that consumes webhook events.

Conditionally required

VariableHelm value nameDefaultDescription
INSTANCE_NAMEbackend.instance.nameundefinedYour Rafiki instance’s name used to communicate for auto-peering and/or telemetry. Required when auto-peering and/or telemetry is enabled

Optional

VariableHelm value nameDefaultDescription
ADMIN_PORTbackend.port.admin3001The port of your Backend Auth API server.
ADMIN_API_SIGNATURE_TTL_SECONDSundefined30The TTL, in seconds, for which a request’s signature will be valid.
API_SECRETundefinedundefinedN/A
API_SIGNATURE_VERSIONundefined1The version of the request signing algorithm used to generate signatures.
AUTO_PEERING_SERVER_PORTbackend.autoPeering.serverPort3005If auto-peering is enabled, the server will use this port.
CONNECTOR_PORTbackend.port.connector3002The port of the ILP connector for sending packets via ILP over HTTP.
ENABLE_AUTO_PEERINGbackend.enable.autoPeeringfalseWhen true, auto-peering is enabled.
ENABLE_MANUAL_MIGRATIONSbackend.enableManualMigrationsfalseWhen true, you must run the database manually with the command npm run knex – migrate:latest –env production
ENABLE_SPSP_PAYMENT_POINTERSbackend.enable.spspPaymentPointerstrueWhen true, the SPSP route is enabled.
ENABLE_TELEMETRYundefinedfalseEnables the telemetry service on Rafiki.
ENABLE_TELEMETRY_TRACESundefinedfalseN/A
EXCHANGE_RATES_LIFETIMEbackend.lifetime.exchangeRate15_000The time, in milliseconds, the exchange rates you provide via the EXCHANGE_RATES_URL are valid.
GRAPHQL_IDEMPOTENCY_KEY_LOCK_MSbackend.idempotency.keyLockMs2000The TTL, in milliseconds, for idempotencyKey concurrency lock on GraphQL mutations on the Backend Admin API.
GRAPHQL_IDEMPOTENCY_KEY_TTL_MSbackend.idempotency.keyTTL86400000 (24 hours)The TTL, in milliseconds, for idempotencyKey on GraphQL mutations on the Backend Admin API.
INCOMING_PAYMENT_CREATED_POLL_FREQUENCY_MSundefined1000N/A
INCOMING_PAYMENT_CREATED_POLL_TIMEOUT_MSundefined10000N/A
INCOMING_PAYMENT_EXPIRY_MAX_MSbackend.incomingPayment.expiryMaxMs2592000000 (30 days)The maximum into the future, in milliseconds, incoming payments expiry can be set to on creation.
INCOMING_PAYMENT_WORKER_IDLEbackend.workerIdle200The time, in milliseconds, that INCOMING_PAYMENT_WORKERS will wait until checking an empty incoming payment request queue again.
INCOMING_PAYMENT_WORKERSbackend.workers.incomingPayment1The number of workers processing incoming payment requests.
LOG_LEVELbackend.logLevelinfoPino log level
MAX_OUTGOING_PAYMENT_RETRY_ATTEMPTSundefined5Specifies how many times an outgoing payment is retried before failing completely
NODE_ENVIRONMENTbackend.nodeEnvdevelopmentThe type of node environment: development, test, or production.
OPEN_PAYMENTS_PORTbackend.port.openPayments3003The port of your Open Payments resource server.
OPEN_TELEMETRY_COLLECTOR_URLSundefined*undefinedN/A
OPEN_TELEMETRY_EXPORT_INTERVALundefined15000N/A
OPEN_TELEMETRY_TRACE_COLLECTOR_URLSundefinedundefinedN/A
OUTGOING_PAYMENT_WORKER_IDLEbackend.workerIdle200The time, in milliseconds, that OUTGOING_PAYMENT_WORKERS wait until they check an empty outgoing payment request queue again.
OUTGOING_PAYMENT_WORKERSbackend.workers.outgoingPayment4The number of workers processing outgoing payment requests.
POLL_INCOMING_PAYMENT_CREATED_WEBHOOKundefinedfalseN/A
PRIVATE_KEY_FILEbackend.key.fileundefinedThe path to your Rafiki instance’s client private key.
QUOTE_LIFESPANbackend.lifetime.quote5 * 60_000 (5 minutes)The time, in milliseconds, an Open Payments quote is valid for.
REDIS_TLS_CA_FILE_PATHbackend.redis.tlsCaFile''Redis TLS config
REDIS_TLS_CERT_FILE_PATHbackend.redis.tlsCertFile''Redis TLS config
REDIS_TLS_KEY_FILE_PATHbackend.redis.tlsKeyFile''Redis TLS config
SIGNATURE_SECRETbackend.quoteSignatureSecretundefinedThe secret to generate request header signatures for webhook event requests.
SIGNATURE_VERSIONbackend.signatureVersion1The version number to generate request header signatures for webhook events.
SLIPPAGEbackend.ilp.slippage0.01 (1%)The accepted ILP rate fluctuation.
STREAM_SECRETbackend.ilp.streamSecretundefinedThe seed secret to generate shared STREAM secrets.
TELEMETRY_EXCHANGE_RATES_LIFETIMEundefined86_400_000N/A
TELEMETRY_EXCHANGE_RATES_URLundefinedhttps://telemetry-exchange-rates.s3.amazonaws.com/exchange-rates-usd.jsonThe endpoint Rafiki will query for exchange rates. Used as a fallback if/when exchange rates aren’t provided.
TIGERBEETLE_CLUSTER_IDundefined0The TigerBeetle cluster ID picked by the system that starts the TigerBeetle cluster to create a TigerBeetle client.
TIGERBEETLE_REPLICA_ADDRESSESundefined3004TigerBeetle replica addresses for all replicas in the cluster. The addresses are comma-separated IP addresses/ports, to create a TigerBeetle client.
TIGERBEETLE_REPLICA_ADDRESSES.SPLITundefined3004N/A
TIGERBEETLE_TWO_PHASE_TIMEOUT_SECONDSundefined5N/A
TRUST_PROXYbackend.trustProxyfalseWhen true, the X-Forwarded-Proto header is used to determine if connections are secure.
WALLET_ADDRESS_DEACTIVATION_PAYMENT_GRACE_PERIOD_MSbackend.walletAddress.deactivationPaymentGratePeriodMs86400000 (24 hours)The time into the future, in milliseconds, to set expiration of Open Payments incoming payments when deactivating a wallet address.
WALLET_ADDRESS_LOOKUP_TIMEOUT_MSbackend.walletAddress.lookupTimeoutMs1500The time, in milliseconds, you have to create a missing wallet address before timeout.
WALLET_ADDRESS_POLLING_FREQUENCY_MSbackend.walletAddress.pollingFrequencyMs100The frequency of polling while waiting for you to create a missing wallet address.
WALLET_ADDRESS_URLbackend.serviceUrls.WALLET_ADDRESS_URLhttp://127.0.0.1:3001/.well-known/payYour Rafiki instance’s internal wallet address.
WALLET_ADDRESS_WORKER_IDLEbackend.workerIdle200The time, in milliseconds, that WALLET_ADDRESS_WORKERS wait until checking the empty wallet address request queue again.
WALLET_ADDRESS_WORKERS`backend.workers.walletAddress1The number of workers processing wallet address requests.
WEBHOOK_MAX_RETRYbackend.webhookMaxRetry10The maximum number of times your Rafiki instance’s backend retries sending a certain webhook event to your configured WEBHOOK_URL.
WEBHOOK_TIMEOUTbackend.lifetime.webhook2000 (2 seconds)The time, in milliseconds, that your Rafiki instance will wait for a 200 response from your webhook endpoint. If a 200 response is not received, Rafiki will time out and try to send the webhook event again.
WEBHOOK_WORKER_IDLEbackend.workerIdle200The time, in milliseconds, that WEBHOOK_WORKERS will wait until they check the empty webhook event queue again.
WEBHOOK_WORKERSbackend.workers.webhook1The number of workers processing webhook events.
WITHDRAWAL_THROTTLE_DELAYbackend.withdrawalThrottleDelayundefinedThe delay in liquidity withdrawal processing.