# Backend

## Endpoints needed for Card

In order to communicate with Ledger’s backend, you must provide standardised APIs for Ledger's CARD aggregator services to call.

> **Note:** You will find all the information regarding the CARD endpoints <a href="../redoc-api" target="_blank">here</a>, as well as additional details on
> some endpoints below.

You need to implement following endpoint for the card: - To create a signed fund binary payload: [/sell](../redoc-api#operation/postSell).

Additional Details: POST /sell

Example request payload:

```json copy
{
  "quoteId": "string",
  "amount": "string",
  "refundAddress": "string",
  "fromCryptoCurrency": "string",
  "toFiatCurrency": "string",
  "payloadCryptoCurrency": "string",
  "nonce": "number"
}
```

An example response from the your backend to the Ledger backend

```json copy
{
  "sellId": "SELL-ID-165940",
  "payinAddress": "0xa0b86991c627e936c1d19d4a2e90a2ce3606eb48",
  "createdAt": "2030-05-26T14:13:39",
  "providerFees": "0.0001",
  "referralFees": "0.0001",
  "payoutNetworkFees": "0.0002",
  "providerSig": {
    "payload": "CgUweGZmZhoFMHhmZmYqBTB4ZmZmOgNCVENCA0JBVEoIMTIwMDAwMDBSCDExNTAwMDAwWhF2ZXJ5IGxvbmd1ZSBub25jZQ==",
    "signature": "MEUCIBRm4PrdgRw0aBwRepuOGGRmR/YPcCoyKNJ7UDjFO030AiEA/VT0anolum0a3X/9lGPeovZHqzeDG9brcUB4zhYmwbs="
  }
}
```

Your Protobuf message should have the following structure:

```go copy
syntax = "proto3";
package ledger_sell;

// (coefficient) * 10^(- exponent)
message UDecimal {
    bytes  coefficient = 1;
    uint32 exponent = 2;
}

message NewSellResponse {
    string   trader_email = 1;
    string   in_currency = 2;
    bytes    in_amount = 3;
    string   in_address = 4;
    string   out_currency = 5;
    UDecimal out_amount = 6;
    bytes    device_transaction_id = 7;
    string   in_extra_id = 8;            // memo
}
```

`in_amount` amount must be in the lowest unit of the coin, encoded into a 16 bytes array in big endian.

- 1 **BTC** would be `0x5F5E100` (100000000 in hexadecimal). The smallest unit is a **satoshi** which is `10^-8` **BTC**.
  So multiply 1 **BTC** by `10^8` → `0x5F5E100`.
  And `0x5F5E100` encoded into a 16 bytes array in big endian is `[0x00, ... 0x00, 0x05, 0xF5, 0xE1, 0x00]`.
- 2 **ETH** would be `0x1BC16D674EC80000` (or 2000000000000000000). The smallest unit is a **wei** which is `10^-18` **ETH**.
  So multiply 2 **ETH** by `10^18` → `0x1BC16D674EC80000`.
  And `0x1BC16D674EC80000` encoded into a 16 bytes array in big endian is `[0x00, ... 0x00, 0x1B, 0xC1, 0x6D, 0x67, 0x4E, 0xC8, 0x00, 0x00]`.

## Real-time Status Updates:

To ensure effective communication with Ledger's backend, you are required to implement a webhook [/transaction/\{sellId}/status](../redoc-api#operation/statusUpdate) update mechanism. This should notify Ledger real-time whenever there is a change in the status of a transaction. Ledger will provide partners with the necessary webhook URL or address to which the status updates should be sent.

Additional Details: POST /transaction/\{sellId}/status
Explanation of the different output `status`:

- `FINISHED`: Trade has been completed successfully (user has received payout transaction).
- `EXPIRED`: Payin transaction was not received in time, trade is cancelled. User will be refunded if payin transaction is received afterwards.
- `ON_HOLD`: Trade has been put on hold (eg: for KYC reasons). User must contact support.
- `PENDING`: Trade is in progress (provider is waiting to receive payin transaction, or user is waiting to receive payout transaction)
- `TRANSFER_IN_COMPLETED`: Transfer in completed and waiting for transfer out to be sent.
- `REFUNDED`: Trade has been cancelled, refund transaction has been successfully received by user.
- `UNKNOWN`: Trade is in unknown state. User must contact support.

Additionally, if your backend needs to know the transaction status from our system (e.g., whether the transaction was approved or rejected by the user’s device), we provide an optional endpoint [/transaction/\{sellId}/status](../redoc-api#operation/getStatusUpdate)

[//]: # "Info needed to be exchange with the provider, but not out loud publicly"

[//]: # "**IP address checking** "

[//]: # "Additionally, we also need a way to know if a user will be able to perform a coin sell given his IP."

[//]: # "Our back-end can adapt to how you decide to do this, but we recommend you use a dedicated endpoint. Our back-end will send the user’s IP address to that endpoint, without logging it. In response, your endpoint should tell us if the trade is accepted or rejected."

## Payload & Signature

Here is a little diagram to explain how the `payload` and the `signature` are generated:

![Payload and Payload Signature generation diagram](/exchange/payload-signature-generation-sell.png)

- `payload`: the trade parameters are assembled in a [protobuf](https://developers.google.com/protocol-buffers) message. This message is [binary encoded](https://developers.google.com/protocol-buffers/docs/encoding) to produce a Byte Array. This Byte Array is then [base64Url encoded](https://en.wikipedia.org/wiki/Base64), resulting `payload` field.
- `signature`: The payload is signed using [ES256](https://ldapwiki.com/wiki/Wiki.jsp?page=ES256) provider's private key, generating a Byte Array. This Signature Byte Array is then [base64Url encoded](https://en.wikipedia.org/wiki/Base64), producing the Signature field. ([more details](#jws-signature)).

If you need help with the signing process, please refer to our code [examples](code-examples.mdx).

### Generate Private/Public Key

1. **Private Key**:
   Use the following command to generate the private key:

   ```bash
   openssl ecparam -name secp256k1 -genkey -noout -out sample-priv-key-secp256k1.pem
   ```

2. **Public Key**:
   Derive the public key from the private key using the command:
   ```bash
   openssl ec -in sample-priv-key-secp256k1.pem -pubout > sample-pub-key-secp256k1.pem
   ```

### Verify Key Information

To inspect the contents of the private key file:

```bash
openssl ec -text -in sample-priv-key-secp256k1.pem
```

Repeat this process for both the **production** and **test** environments to generate two distinct key pairs.

### Signature usage

- Payload and Signature\
  From the provider to . The payload is a protobuf message containing the trade data. It is generated by the provider and sent to .

```go copy
type Payload struct {
  trader_email,
  in_currency,
  in_amount,
  in_address,
  out_currency,
  out_amount,
  device_transaction_id,
  in_extra_id
}
R, S := Sign(payload, privKey)
```

- Validate\
  Exchange app checks and validates the payload (signature and content).

```go copy
// Compare nonce in payload
Verify((R, S), payload, pubKey)
```

- Display\
  Exchange app requests approval to the user by displaying the operation summary on screen.

```c copy
Validate?
Send currency_from amount_to_provider
Receive currency_to amount_to_wallet
```
