stellar / java-stellar-anchor-sdk

Java SDK for the Stellar network anchor development.
Apache License 2.0
37 stars 34 forks source link

Feature Request: Support onchain-onchain deposit and withdrawals #1479

Open philipliu opened 3 months ago

philipliu commented 3 months ago

Summary

To support onchain-onchain deposits and withdrawals in SEP-6 and SEP-24, we propose extending the existing exchange functionality. Currently, SEP-6 and SEP-24 limit source_asset (for deposits) and destination_asset (for withdrawals) to ISO 4217 assets, which aligns with the typical on-ramp/off-ramp use case. However, this restriction is not a fundamental requirement for deposits or withdrawals.

SEP-38 will be utilized to provide quotes for onchain-onchain transactions. The protocol (SEP-38) does not inherently restrict one of the assets to be an off-chain asset, so no changes are needed in the protocol itself.

On the Anchor Platform side, updates will be made to the RPCs and SEP (SEP-6 and SEP-24) transaction creation to relax some validations on source_asset and destination_asset. The RequestOnchainFunds RPC will be updated to handle both deposits and withdrawals for onchain-onchain transactions. These changes can be implemented in a non-breaking manner, allowing them to be included in version 3.1.

Protocol Changes

SEP-6 Deposit

Summary:

Request (deposit USDC for SRT): GET [TRANSFER_SERVER]/deposit-exchange?source_asset=stellar:USDC:G...&destination_asset=SRT&...&type=stellar

GET /transaction or GET /deposit-exchange Response:

{
  "instructions": {
    "organization.crypto_address": {
      "value": "G...",
      "description": "Anchor generated deposit address"
    },
    "organization.bank_account_number": {
      "value": "13719713158835300",
      "description": "Anchor generated deposit text memo"
    }
  },
  "how": "Send 10 USDC to the address G... with 13719713158835300 as the text memo"
}
Alternative Approach

We could include withdraw_anchor_accountwithdraw_memo, and withdraw_memo_type in the response. This provides a structured response that wallets can easily parse, but it requires wallet support for implementation.

Considerations

Reusing the instructions field is lightweight and does not require wallet implementation for onchain-onchain deposits. However, the user experience (UX) may be awkward. Users, already in the wallet, would need to copy the deposit information, exit the deposit flow UI, and submit a transaction to the Anchor's deposit address.

To improve UX, we can define standard values/descriptions when the crypto_address is a Stellar account, allowing wallets to easily parse this information and create the transaction programmatically. However, if we are considering this, then withdraw_anchor_account approach is preferable.

SEP-6 Withdraw

Summary:

Request (withdraw SRT to USDC): GET [TRANSFER_SERVER]/withdraw-exchange?source_asset=SRT&destination_asset=stellar:USDC:G...&

GET /transaction Response:

{
  "withdraw_anchor_account": "G...",
  "withdraw_memo": "13719713158835300",
  "withdraw_memo_type": "text"
}

Or in the GET /withdraw-exchange response if it can be provided synchronously:

{
  "account_id": "G...",
  "memo": "13719713158835300",
  "memo_type": "text"
}

SEP-24 Deposit

Summary:

Request (deposit USDC for SRT): POST [TRANSFER_SERVER_SEP0024]/transactions/deposit/interactive

{
  "asset_code": "SRT",
  "issuer": "G...",
  "source_asset": "stellar:USDC:G..."
}

Response: Interactive URL link with the deposit instructions on the web page.

SEP-24 Withdraw

Summary:

Request (withdraw SRT to USDC): POST [TRANSFER_SERVER_SEP0024]/transactions/withdraw/interactive

{
  "asset_code": "SRT",
  "issuer": "G...",
  "destination_asset": "stellar:USDC:G..."
}

Response: Interactive URL link with the deposit instructions on the web page.

Anchor Platform Changes

RPC

The RequestOnchainFunds RPC is currently called by the business server during the withdraw (exchange) flows. Moving forward, the business server will also call this RPC for exchange transactions where both assets are Stellar assets, meaning it will be used in both deposit and withdraw flows. The RPC currently validates that the amount_out.asset is not a Stellar asset. This validation will be updated to allow amount_out.asset to be a Stellar asset for exchange transactions.

Config

Using SRT as an example, if USDC <-> SRT is supported and if a business also wants to support USD <-> SRT, there is no need to change the asset config schema. The asset config should include USDC and SRT with deposit/withdraw enabled, and the counter asset correctly set in the sep38.exchangable_assets list.

If USD <-> SRT should not be supported, a new field called swap_only can be added under the deposit/withdraw operations. Enabling swap_only would disable USD <-> SRT transactions.

JakeUrban commented 2 months ago

Thanks @philipliu, its great to hear we can support onchain/onchain transactions without breaking changes to the SEP and Anchor Platform APIs.

However, it does sound like clients would have to update their implementations for the SEP-6 and SEP-24 deposit cases, given that they make the assumption that the transfer of funds is offchain and therefore they don't need to facilitate an onchain payment to the anchor.

To avoid this and make things simpler, I propose leaving the deposit endpoints for both SEP-6 and SEP-24 unchanged, and only supporting onchain/onchain transactions via the withdraw endpoints.

Clients already expect to make onchain payments when facilitating withdraw flows, so they could use the withdraw_anchor_account, withdraw_memo, and withdraw_memo_type as they always do. We wouldn't have to update the instructions object or SEP-9 fields to provide stellar accounts and memos.

JakeUrban commented 2 months ago

Also, I don't see the need for the swap_only config attribute. If USD <-> SRT isn't supported, then iso4217:USD shouldn't be listed as an exchangeable asset for stellar:SRT:G... and vice versa.

lijamie98 commented 2 months ago

In SEP-6 deposit, withdraw_anchor_account (etc) are used for withdraw transactions. I think it would be confusing to re-use these fields.

lijamie98 commented 2 months ago

Do we need the destination_asset in the response?

{
  "destination_asset": "stellar:USDC:G..."
}
lijamie98 commented 2 months ago

@JakeUrban @Ifropc Taking a million steps back, I feel it is weird to use deposit and withdraw endpoints for on-chain assets exchange.

Aren't these the same? (USDC -> SRT)

philipliu commented 2 months ago

Do we need the destination_asset in the response?

{
  "destination_asset": "stellar:USDC:G..."
}

This was a typo. Fixed!

lijamie98 commented 2 months ago

Isn't it a duplicate with the request param? GET [TRANSFER_SERVER]/withdraw-exchange?source_asset=SRT&**destination_asset**=stellar:USDC:G...&