Skip to content
GitHub

Peer ASE A and ASE B Rafiki instances

With ASE A (using Test Wallet) and ASE B (using Interledger App Wallet) deployed on their own Kubernetes clusters, this guide explains how to:

  • Expose the Rafiki connector endpoints on each side.
  • Create assets, peers, and accounts in both Rafiki instances.
  • Enable Interledger payments between the two wallets.

This guide assumes:

  • ASE A deployment is complete:
    • Rafiki Admin: https://rafiki-admin.ase-a.example.com
    • Rafiki backend (Open Payments): https://rafiki.ase-a.example.com
    • ILP address (example): test.ase-a
  • ASE B deployment is complete:
    • Rafiki Admin: https://rafiki-admin.ase-b.example.com
    • Rafiki backend (Open Payments): https://rafiki.ase-b.example.com
    • ILP address (example): test.ase-b

The Rafiki backend services expose an ILP connector port (default 3002). In both rafiki-*.values.yaml files, this is typically configured as:

backend:
ilp:
connector: 'http://<rafiki-backend-service>.<namespace>:3002'

For peering, each Rafiki must be able to reach the other Rafiki’s connector endpoint over HTTP(S).

In many cases, you will expose the ILP connector alongside the Open Payments API via Kubernetes Service and Ingress. Ensure that:

  • The backend service includes port 3002 (connector).
  • The ingress route forwards ILP traffic to that port.

Your Rafiki Helm chart should already create a backend service with ports:

  • 3000 – Open Payments
  • 3001 – Admin / GraphQL
  • 3002 – ILP connector

Confirm:

Terminal window
kubectl get svc rafiki-ase-a-backend-service -n rafiki-ase-a -o yaml

You should see a port named connector (or similar) on 3002. Repeat for ASE B:

Terminal window
kubectl get svc rafiki-ase-b-backend-service -n rafiki-ase-b -o yaml

If you expose ILP over HTTPS under /ilp, your ingress for the backend might look like:

spec:
rules:
- host: rafiki.ase-a.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rafiki-ase-a-backend-service
port:
number: 3000
- path: /ilp
pathType: Prefix
backend:
service:
name: rafiki-ase-a-backend-service
port:
number: 3002

Do the same for ASE B (rafiki.ase-b.example.com). This should result in connector URLs like:

  • ASE A connector: https://rafiki.ase-a.example.com/ilp
  • ASE B connector: https://rafiki.ase-b.example.com/ilp

This section shows how to configure matching assets and peer relationships on both Rafiki instances using the Admin GraphQL API. All requests must be authenticated using the tenant’s ADMIN_API_SECRET and include a tenant-id header. Refer to Backend service authentication for details.

For a simple demo:

  • Asset (both sides): USD, scale 2
  • ILP addresses:
    • ASE A: test.ase-a
    • ASE B: test.ase-b
  • HTTP auth tokens (shared secrets):
    • ase-a-to-ase-b-token: Token ASE A uses when sending packets to ASE B (ASE B’s incoming token).
    • ase-b-to-ase-a-token: Token ASE B uses when sending packets to ASE A (ASE A’s incoming token).

First, create the USD asset on ASE A. Send the following GraphQL mutation to https://rafiki.ase-a.example.com/graphql:

mutation CreateAsset($input: CreateAssetInput!) {
createAsset(input: $input) {
code
success
message
asset {
id
code
scale
tenantId
}
}
}

Save the asset.id from the response. You’ll need it when creating the peer.

Create a peer representing ASE B. Use the asset ID from the previous step:

mutation CreatePeer($input: CreatePeerInput!) {
createPeer(input: $input) {
code
success
message
peer {
id
name
staticIlpAddress
asset {
code
scale
}
liquidity
liquidityThreshold
}
}
}

Create the USD asset on ASE B. Send the following GraphQL mutation to https://rafiki.ase-b.example.com/graphql:

mutation CreateAsset($input: CreateAssetInput!) {
createAsset(input: $input) {
code
success
message
asset {
id
code
scale
tenantId
}
}
}

Save the asset.id from the response for the next step.

Create a peer representing ASE A. Use the asset ID from the previous step and ensure the HTTP auth tokens are symmetric with ASE A’s configuration:

mutation CreatePeer($input: CreatePeerInput!) {
createPeer(input: $input) {
code
success
message
peer {
id
name
staticIlpAddress
asset {
code
scale
}
liquidity
liquidityThreshold
}
}
}

Use GraphQL queries to verify that both peers are configured correctly and healthy.

Query all peers on ASE A to verify the peer was created:

query GetPeers {
peers {
edges {
cursor
node {
id
name
staticIlpAddress
asset {
code
scale
}
liquidity
liquidityThreshold
http {
outgoing {
endpoint
}
}
}
}
}
}

Query all peers on ASE B to verify the peer was created:

query GetPeers {
peers {
edges {
cursor
node {
id
name
staticIlpAddress
asset {
code
scale
}
liquidity
liquidityThreshold
http {
outgoing {
endpoint
}
}
}
}
}
}

After creating peers on both sides, verify that:

  • Each Rafiki instance has a USD asset with matching code and scale.
  • Each Rafiki instance has a peer pointing to the other Rafiki’s ILP address.
  • The connector endpoints are reachable (check network connectivity).
  • HTTP auth tokens are symmetric between both peers.

You can also check peer health using the Rafiki Admin UI at:

  • https://rafiki-admin.ase-a.example.com (ASE A)
  • https://rafiki-admin.ase-b.example.com (ASE B)

Navigate to Peers and verify that peer status shows READY or HEALTHY.

Once peering has been set up and verified, Interledger payments should be possible between users of ASE A (Test Wallet) and ASE B (Interledger App Wallet). Users can send payments between the two wallets using their wallet addresses, and the payments will flow through the peered Rafiki instances.

  • Peer not healthy:
    • Double-check connector URLs and that the ILP connector port (3002) is accessible via Ingress.
    • Verify HTTP auth tokens and ILP addresses match on both sides.
    • Check Rafiki backend logs for connection or authentication errors.
  • Payments failing or stuck:
    • Ensure assets, peers, and accounts are correctly linked.
    • Confirm sufficient liquidity / limits on both peers and accounts.
    • Check wallet logs for any issues constructing Open Payments requests.
  • TLS / DNS issues:
    • Verify DNS records point to the correct ingress IPs.
    • Confirm TLS certificates are valid and that Rafiki is configured to trust any intermediate proxies (trustProxy: "true" where required).