# SLIP-0024 Transaction payload signing

### Overview

When a hardware wallet receives transaction data from a third-party API, there's no built-in way to verify the data hasn't been tampered with in transit. A man-in-the-middle attacker could alter addresses or amounts before they reach the signing device, and the wallet would have no way to detect it.

SwapKit's `/v3/swap` endpoint now supports [SLIP-0024](https://github.com/satoshilabs/slips/blob/master/slip-0024.md) signed payloads to solve this problem. SLIP-0024 is a SatoshiLabs standard that defines a secure payment request format originally designed for hardware wallets like Trezor and BitBox. When activated for your integration, the `/v3/swap` response includes a `slip24` object containing a cryptographically signed representation of the transaction. Your device or application can verify this signature using SwapKit's public key, ensuring the payload is authentic and unmodified.

### How It Works

**Signature Flow**

1. Your application calls `/v3/swap` as normal (see [Quote and Swap Implementation Flow](https://docs.swapkit.dev/swapkit-api/quote-and-swap-implementation-flow)).
2. SwapKit builds the transaction (`tx`) and generates the `slip24` object.
3. The `slip24` payload is serialized to a buffer using the configured encoding scheme, then signed with SwapKit's private key.
4. The response includes both the standard `tx` field and the `slip24` object with its `signature`.
5. Your application or hardware wallet firmware verifies the signature against SwapKit's public key. If valid, the device can display a human-readable confirmation to the user (e.g., "Send 0.00298567 BTC to SWAPKIT (NEAR)") instead of raw addresses.

**Key Management**

* SwapKit generates a dedicated key pair for each integrator. The **private key** is stored encrypted, only the production service can decrypt it. Even SwapKit developers cannot access the plaintext key.
* The **public key** is shared privately with the integrator during onboarding. It is not sensitive and is what your application uses to verify signatures.
* Supported key pair algorithms: **ES256** and **secp256k1**.

### Signature Schemes

Three signature schemes are available. The scheme is configured per integration during onboarding. The default is `basic`.

* **basic (raw): t**he `tx` property from the `/v3/swap` response is converted directly to a buffer and signed. This is the default scheme.
* **slip24\_hex: t**he `tx` property is converted to its SLIP-0024 representation, serialized into a **hex-encoded** buffer, and then signed.
* **slip24\_base64: s**ame as `slip24_hex`, but the SLIP-0024 representation is serialized into a **base64-encoded** buffer before signing.

| Scheme          | Payload Source                   | Encoding   | Default |
| --------------- | -------------------------------- | ---------- | ------- |
| `basic` / `raw` | `tx` field directly              | raw buffer | Yes     |
| `slip24_hex`    | SLIP-0024 representation of `tx` | hex        | No      |
| `slip24_base64` | SLIP-0024 representation of `tx` | base64     | No      |

### Response Payload

**The slip24 Object**

When SLIP-0024 signing is active for your API key, the `/v3/swap` response includes a `slip24` field alongside the standard fields documented in the [/v3/swap endpoint reference](https://docs.swapkit.dev/swapkit-api/v3-swap-obtain-swap-transaction-details).

```json
{
  "slip24": {
    "recipientName": "SWAPKIT (NEAR)",
    "nonce": null,
    "memos": [
      {
        "type": "coinPurchase",
        "coinPurchase": {
          "coinType": 0,
          "amount": "0.00298567 BTC",
          "address": "bc1qa2gkyk5xx8v706fesud0fd0skf8dvtjz45fmxn"
        }
      }
    ],
    "outputs": [
      {
        "amount": 10000000000000000,
        "address": "0xEC2F9Cd3E2aFbaeb83f959382584aE2b8BB66Ac3"
      }
    ],
    "signature": "Qz1+JXGa7L4YPZLxCmGeILFpx1VewPLbHD9tlxERjrJuSEHw5QuNWYkxRv6CFomIplFZ3pvEjbKINVBXFXMlYg=="
  },
  "swapId": "62fbdbf5-bc8f-445b-920a-9b5c4a778606"
}
```

**Field Reference**

* **`recipientName`**: Human-readable name displayed on the hardware wallet screen (e.g., `"SWAPKIT (NEAR)"`). Identifies the service and destination chain.
* **`nonce`**: Reserved for replay protection. Currently `null`.
* **`memos`**: Array of memo objects describing the transaction. Each has a **`type`** and a corresponding data object.
  * **`coinPurchase.coinType`**: SLIP-0044 coin type identifier (e.g., `0` for Bitcoin).
  * **`coinPurchase.amount`**: Human-readable amount string (e.g., `"0.00298567 BTC"`).
  * **`coinPurchase.address`**: Destination address for the purchased asset.
* **`outputs`**: Array of transaction outputs with raw **`amount`** (in smallest denomination) and **`address`**.
* **`signature`**: Cryptographic signature over the SLIP-0024 payload. Verify this against SwapKit's public key using the configured algorithm.

### Verification

From the integrator's perspective, the verification flow is:

1. Extract the `slip24` object from the `/v3/swap` response.
2. Serialize the payload (excluding the `signature` field itself) using the agreed-upon encoding scheme.
3. Verify the `signature` against the serialized buffer using SwapKit's public key and the configured algorithm (ES256 or secp256k1).
4. If verification passes, the transaction data is authentic. The hardware wallet can safely display the human-readable details (recipient name, amount, and address) to the user for confirmation.
5. If verification fails, reject the transaction. The payload may have been tampered with.

### Best Practices

* **Always verify before displaying**: Never show transaction details to the user before the signature has been validated.
* **Pin the public key**: Store SwapKit's public key securely in your application or firmware. Don't fetch it dynamically at verification time.
* **Handle verification failures gracefully**: If signature verification fails, block the transaction and surface a clear error to the user. Do not fall back to unsigned mode silently.
* **Use `recipientName` for UX**: The `recipientName` field is designed for display on constrained hardware wallet screens. Show it alongside the amount to give users a clear confirmation prompt.
* **Stay coordinated on key changes**: If SwapKit rotates keys or adds new signature schemes, you'll be notified through the onboarding relationship. Ensure your firmware update pipeline can accommodate key changes.

### Getting Started

SLIP-0024 signing is not self-service. To activate it for your integration, contact SwapKit directly. During onboarding, SwapKit will:

* Generate a dedicated key pair for your integration
* Share the public key privately
* Configure your preferred signature scheme (`basic`, `slip24_hex`, or `slip24_base64`) and algorithm (`ES256` or `secp256k1`)

SwapKit is open to working with any hardware wallet manufacturer or payment processor that needs cryptographic verification of transaction payloads.

***

For questions or to begin integration, reach out to SwapKit directly through [the partnership portal](https://partnerships.swapkit.dev) or [Discord](https://discord.gg/swapkit).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.swapkit.dev/spotlights/slip-0024-transaction-payload-signing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
