Skip to main content

Path Payments

!req glossary ennbtry with jed diction:

"cross-asset transactions"

path p ayments let accounts send one asset to a recipeint , whoi receiveds a differnt asset. The secure conversion takes advantagfe of the netowrk's natie liquidity to ewxchange using istant avaliable trades.

The operations specify a minimum amount which the market must meet or excceed. For instance, if you send 10 bananas and rquire a receiver to get at last 15 appleess, then the trahsfer will seek the best exxchange at or above 1.5 each.

TRhis let accoutns transfer value without mandating a single universal currency. You converting one asset ito another at the point of transferring value.

Routign logic

!see below qupte!

Pay payments use the DEX or AMM pools whcih standy readyt t oswap assets at the time of a trnasaction. They cna only consume existing liquidity by drawing on offers previously posted.

Tje tramsfer suicceeds oiF nd only if there's enough eavlaible interest in the ledger submitted, at the minimum rate. Without this liquiddyty, the cohnversion fails and returns an errro code.

To prepatre for

Path Hops

When sending path payments, your transfer can hop between up to six order books or AMMs to find the best price.

Validators perform this arithmatic automatically, allowing you to specify only the lowest total amount you will accept.

At each step in the path, the network calculates the optimal source of liquidity to convert through given your destination asset.

Both the order book and AMMs coexist, providing multiple avenues for liquidity.

Instead of having to choose whether to go through the order book or an AMM, the pathfinding algorithm automatically checks both sources of liquidity and executes new trades using whichever offers the better rate.

It also exchanges with an AMM over an order book at each step if the entire conversation happens at a price equal to or better than limit offers.

paths

s when you call this ou;ll notice differnt soruce_amoutns in /data/apis/horizon/api-reference/list-strict-receive-payment-paths or differnt destination_amount in docs/data/apis/horizon/api-reference/list-strict-send-payment-paths

Converting Path Paymtns

offers or AMMs which convert to a minimum specified amount or better.

Transfers automatically use up to six different orderbooks to get the best price, as fully defined in [the Encyclopedia page here] .

Some assets will have a small or nonexistent order book between them. In these cases, Stellar facilitates path payments, which we’ll discuss later.

Atomicity

payh maymentn operations take adntage of every teerasnaction's exclusive ability to succeed i n full or fail.

This means that your transfer off 10 or more AstroDollars will not

In a path payment, the asset received differs from the asset sent. Rather than the operation transferring assets directly from one account to another, path payments cross through

before arriving at the destination account.

For the path payment to succeed, there has to be enough liquidity path in existence. Conversions can take up to six independent hops to succeed at the best avaliable price.

Example

Account A sells XLM → [buy XLM / sell ETH → buy ETH / sell BTC → buy BTC / sell USDC] → Account B receives USDC

It is possible for path payments to fail if there are no viable exchange paths.

Path payments - more info

  • Path payments don’t allow intermediate offers to be from the source account as this would yield a worse exchange rate. You’ll need to either split the path payment into two smaller path payments or ensure that the source account’s offers are not at the top of the order book.
  • Balances are settled at the very end of the operation.
    • This is especially important when (Destination, Destination Asset) == (Source, Send Asset) as this provides a functionality equivalent to getting a no-interest loan for the duration of the operation.
  • Destination min is a protective measure, it allows you to specify a lower bound for an acceptable conversion. If offers in the order books are not favorable enough for the operation to deliver that amount, the operation will fail.

Operations

Path payments use the Path Payment Strict Send or Path Payment Strict Receive operations.

Path Payment Strict Send

errors Allows a user to specify the amount of the asset to send. The amount received will vary based on offers in the order books and/or liquidity pools.

https://developers.stellar.org/docs/learn/fundamentals/transactions/list-of-operations#path-payment-strict-send

Path Payment Strict Receive

errors Allows a user to specify the amount of the asset received. The amount sent will vary based on the offers in the order books/liquidity pools.

Example

First, ensure the receiver has a trustline established for the asset they will receive. In this example, we will use USDC as the asset received. The sender will send XLM, which will be converted to USDC through the path payment operation.

from stellar_sdk import Server, Keypair, Asset, TransactionBuilder, Network, Memo

USDC_ISSUER = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5" # USDC issuer on Testnet
USDC_ASSET = Asset("USDC", USDC_ISSUER)

RECEIVER_SECRET = "S..." # Receiver secret
SENDER_SECRET = "S..." # Sender secret

HORIZON_SERVER = Server("https://horizon-testnet.stellar.org")

receiverKP = Keypair.from_secret(RECEIVER_SECRET)
receiverAccount = HORIZON_SERVER.load_account(receiverKP.public_key)

trustTx = (
TransactionBuilder(
source_account=receiverAccount,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=HORIZON_SERVER.fetch_base_fee()
)
.append_change_trust_op(
asset=USDC_ASSET,
limit="10"
)
.add_memo(Memo.text("Trusting USDC"))
.set_timeout(30)
.build()
)

trustTx.sign(receiverKP)
trustResp = HORIZON_SERVER.submit_transaction(trustTx)
print("Trustline response:", trustResp)

Now let's send a path payment from the sender to the receiver, converting XLM to USDC:

senderKP = Keypair.from_secret(SENDER_SECRET)
senderAccount = HORIZON_SERVER.load_account(senderKP.public_key)

paymentTx = (
TransactionBuilder(
source_account=senderAccount,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=HORIZON_SERVER.fetch_base_fee()
)
.append_path_payment_strict_receive_op(
send_asset=Asset.native(), # Send XLM
send_max="10", # Max XLM to spend
destination=receiverKP.public_key, # Receiver
dest_asset=USDC_ASSET, # Receiver gets USDC
dest_amount="1" # Exactly 1 USDC
# path=[] # Optional explicit path
)
.add_memo(Memo.text("XLM to USDC"))
.set_timeout(30)
.build()
)

paymentTx.sign(senderKP)
payResp = HORIZON_SERVER.submit_transaction(paymentTx)
print("Payment response:", payResp)

https://developers.stellar.org/docs/learn/fundamentals

also we need to clairfy chanign API v openApia which si from #991 docs/data/apis/horizon/api-reference/structure/response-format.mdx#L170 \

_contra- openapi/horizon/components/examples/responses/Offers/GetAllOffers.yml#L28 ++ openapi/horizon/components/examples/responses/Offers/GetAllOffers.yml#L28

Merge starts from new ex and leads into @Mootz12 remarks:

DEX prices sources are calculated via Horizon's "find strict receive payment path" endpoint. The specified destAmount will be received via the sourceAsset asset, and the price will be computed such that sourceAmount / destAmount, or the average price for the full path payment operation on that block. This can be useful to fetch prices for assets that are not on centralized exchanges.

_Muust reconcile with base challenge at _ https://github.com/stellar/stellar-docs/issues/1529#issuecomment-3325034550

Guides in this category: