0

I am try to recrate the steps in the Tutorial using Python - Issue a Fungible Token (https://xrpl.org/issue-a-fungible-token.html).

When I try to add an extra step and try to send the funds from the hot address to another (user) account, whereas I set a transfer fee under step 3 - Configure Issuer Settings to some value (e.g. transfer_rate=1020000000), I get the following error:

xrpl.asyncio.transaction.reliable_submission.XRPLReliableSubmissionException: Transaction failed, tecPATH_PARTIAL: Path could not send full amount. 

When I don't set the transfer fee, the sending from the hot address to another address works.

What could be the problem?

My code for generating the an extra user account and trying to send the token from the hot address to it:

hot_wallet_2 = generate_faucet_wallet(client, debug=True)

# Create trust line from hot 2 to cold address -----------------------------------
currency_code = "FOO"
trust_set_tx = xrpl.models.transactions.TrustSet(
    account=hot_wallet_2.classic_address,
    limit_amount=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
        currency=currency_code,
        issuer=cold_wallet.classic_address,
        value="10000000000", # Large limit, arbitrarily chosen
    )
)
ts_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
    transaction=trust_set_tx,
    wallet=hot_wallet_2,
    client=client,
)
print("Creating trust line from hot address 2 to issuer...")
response = xrpl.transaction.send_reliable_submission(ts_prepared, client)
print(response)

# Send token 2 -------------------------------------------------------------------
issue_quantity = "2000"
send_token_tx = xrpl.models.transactions.Payment(
    account=hot_wallet.classic_address,
    destination=hot_wallet_2.classic_address,
    amount=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
        currency=currency_code,
        issuer=cold_wallet.classic_address,
        value=issue_quantity
    )
)
pay_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
    transaction=send_token_tx,
    wallet=hot_wallet,
    client=client,
)
print(f"Sending {issue_quantity} {currency_code} to {hot_wallet_2.classic_address}...")
response = xrpl.transaction.send_reliable_submission(pay_prepared, client)
print(response)
Progman
  • 16,827
  • 6
  • 33
  • 48
simbr
  • 75
  • 1
  • 9

1 Answers1

2

This is expected behavior with transfer fees (regardless of library). Your hot wallet is not exempt from the transfer fee, so you need to set a SendMax to pay for the transfer fee.

For example: if your TransferRate is 1020000000 (2% fee) and you want to transfer 100.00 FOO from your hot address to a customer, you need to send a Payment with an Amount of 100.00 FOO and a SendMax of 102.00 FOO.

In your Python code, I think this should work:

# Send token 2 -------------------------------------------------------------------
issue_quantity = "2000"
transfer_rate = 1.02
send_token_tx = xrpl.models.transactions.Payment(
    account=hot_wallet.classic_address,
    destination=hot_wallet_2.classic_address,
    amount=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
        currency=currency_code,
        issuer=cold_wallet.classic_address,
        value=issue_quantity
    ),
    send_max=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
        currency=currency_code,
        issuer=cold_wallet.classic_address,
        value=(issue_quantity * transfer_rate)
)

In this particular case you probably don't need to provide Paths because the default path (rippling directly through the issuer) is the correct one. That applies any time you're directly transferring a token from one user account to another where both users trust the issuer directly. (Longer paths involving multiple issuers for the same currency code are also possible. The rippling article covers this a little bit.)

mDuo13
  • 136
  • 4
  • Thx. Now it works. I also discovered that if I set the SendMax value to the same value as the Paymnet value, but enable the PartialPayment flag, the transation suceedes but the destinaction account receives only the neto value (value - transfer rate). Is such usage of the PartialPayment flag correct and safe? – simbr Nov 12 '21 at 11:44
  • Yes, that is a valid use of the Partial Payment flag. Note, you often want to provide a DeliverMin value when sending partial payments, since delivering even a minuscule amount at the full cost is a valid outcome with partial payments by default. In this particular case it doesn't matter because the default path is so limited. But for payments that can cross an order book, you may not be always happy with the results (delivering, say, 0.000001 BAR at a cost of 2000 FOO, while a trader in the exchange pockets the spread), so DeliverMin lets you control that a bit more. – mDuo13 Nov 12 '21 at 19:09
  • Can you elaborate a little bit more your example with the payments that cross the order book and the DeliverMin flag or point me to some example, since I can't quite follow your logic. – simbr Nov 15 '21 at 12:22