# Transaction Data

The following information is needed to prepare for and ultimately submit a Kima transaction.

* The fee amount and `feeId`
* The user choice of whether to pay fees from the origin or target chain
* The message containing the transaction details for the user to sign
* The origin token amount the user must authorize so Kima can move tokens on behalf of the user
* The amounts expected when the transaction is submitted

Fortunately, all of these values are calculated by an endpoint exposed by the Kima chain.

Using this endpoint is required as it will return a `feeId` which must be passed to submit endpoints in the backend (`/submit/transfer` or `/submit/swap`).

* Non-BTC origin transactions submitted to Kima without a `feeId` or signature will be rejected
* For non-BTC origin transactions, submitted amounts are validated against the `feeId` and signed message. Any mismatch will result in rejection.

These are security measures to protect the user and ensure the transaction is legitimate.

### Reading token metadata

Use `GET /chains` to read token metadata for the selected origin token.

* `decimals`: use this for amount handling
* `isPermit2`: determines whether submit payload must include `options.permit2`

### BTC-origin note

For BTC-origin transactions, `GET /submit/fees` is still required to get `feeId` and the submit amount.

Before calling `/submit/transfer` or `/submit/swap`, prepare BTC HTLC lock data:

1. `POST /btc/htlc/lock-intent`
2. User broadcasts BTC to the returned `htlcAddress`
3. `POST /btc/htlc/record` using the broadcast `txid`

The values returned by `/btc/htlc/record` are then included in the final submit payload.

### Using the Kima Backend

`GET /submit/fees`

Query Params (all required):

* `amount` (number): the amount of tokens to transfer
* `originAddress` (string): the source user address
* `originChain` (string): the chain the user tokens will come from
* `originSymbol` (string): the token symbol the user will pay with (or bridge from)
* `targetAddress` (string): the receiving address
* `targetChain` (string): the destination chain
* `targetSymbol` (string): the token symbol being delivered

Example:

```
http://localhost:3001/submit/fees?amount=10&originAddress=0x742d35Cc6634C0532925a3b844Bc454e4438f44e&originChain=ARB&originSymbol=USDK&targetAddress=5FHwkrdxkjF7xoL2ncGh4AEYs1KyJzz5MeiaHGz8h8GA&targetChain=SOL&targetSymbol=USDK
```

Port note: these direct backend examples use the backend's default local port `3001`. If your frontend or local proxy exposes the backend on another port such as `4000`, use that URL instead.

Example note: this sample uses `USDK`, which is a testnet token. If you are integrating against mainnet, replace it with a supported mainnet token such as `USDC`.

Success Response:

Amounts are returned as both numbers representing the amount in whole tokens and as a string representing the integer amount in the smallest unit of the token (e.g. USDC is 6 decimals).

* `feeId` (string): a unique identifier for the fee; include this in submit requests
* `feeOrigin*` the gas fee for the origin chain
* `feeKimaProcessing*` The processing fee (currently 0.05%)
* `feeTarget*` the gas fee for the target chain
* `feeTotal*` the total fee in USD
* `transactionValues`: amounts used for token authorization and for submitting the transaction
  * `feeFromOrigin`: amounts used when the user selects to pay fees from the origin amount
    * `allowanceAmount`: the token amount to authorize. For regular ERC-20 tokens this is the value to pass to `approve()`. For Permit2 tokens, use it when building the Permit2 authorization/signature flow.
    * `submitAmount`: the amount that needs to be passed to submit endpoints
  * `feeFromTarget`: amounts used when the user selects to pay fees from the target amount

The response field is still named `allowanceAmount`, but treat it as the origin token authorization amount. There are 2 variants returned depending on whether the user chooses to pay fees from the origin or target amount.

* When paying fees from the origin, use `transactionValues.feeFromOrigin` values.
* When paying fees from the target, use `transactionValues.feeFromTarget`.

Example:

Transferring 10 USDK from ARB to SOL with `0.07371` USD in total fees.

When paying fees from the origin

* The user pays fees on Arbitrum. The total fees are included in the authorization amount.
* User signs the message `I approve the transfer of 10.07371 USDK from ARB to <targetAddress> on SOL.` (`feeFromOrigin.message`)
* The authorization amount is `10.07371` USDK (`feeFromOrigin.allowanceAmount`)
* For regular ERC-20 tokens, use that value in `approve()`. For Permit2 tokens, use it in the Permit2 authorization flow.
* The amount sent to submit endpoint is amount RECEIVED on the target chain
* Therefore the amount sent to submit endpoint is `10` USDK (`feeFromOrigin.submitAmount`)
  * Also included is the `feeId` and signature
* The user receives `10` USDK on Solana

When paying fees from the target chain

* The user does not pay fees on Arbitrum
* User signs the message `I approve the transfer of 10 USDK from ARB to <targetAddress> on SOL.` (`feeFromTarget.message`)
* The authorization amount is `10` USDK (`feeFromTarget.allowanceAmount`)
* For regular ERC-20 tokens, use that value in `approve()`. For Permit2 tokens, use it in the Permit2 authorization flow.
* The amount sent to submit endpoint is `9.926290` USDK (`feeFromTarget.submitAmount`)
* The fees are deducted from the amount received on Solana so the user receives `9.926290` USDK on Solana

Save the corresponding `submitAmount`, `message` and `feeId` for later as they are needed to submit the transaction.

```json
{
  "feeId": "5af06c68-44d6-4079-8e5b-bec1cfa154c7",
  "feeOriginGasFiat": "0.009105",
  "feeOriginGasBigInt": {
    "value": 9105204603000000,
    "decimals": 18
  },
  "feeKimaProcessingFiat": "0.05",
  "feeKimaProcessingBigInt": {
    "value": 50000,
    "decimals": 6
  },
  "feeTargetGasFiat": "0.014605",
  "feeTargetGasBigInt": {
    "value": 14605,
    "decimals": 6
  },
  "feeTotalFiat": "0.07371",
  "feeTotalBigInt": {
    "value": 73710,
    "decimals": 6
  },
  "transactionValues": {
    "feeFromOrigin": {
      "allowanceAmount": {
        "value": 10073710000000000000,
        "decimals": 18
      },
      "submitAmount": {
        "value": 10000000000000000000,
        "decimals": 18
      },
      "message": "I approve the transfer of 10.07371 USDK from ARB to 5FHwkrdxkjF7xoL2ncGh4AEYs1KyJzz5MeiaHGz8h8GA on SOL."
    },
    "feeFromTarget": {
      "allowanceAmount": {
        "value": 10000000,
        "decimals": 6
      },
      "submitAmount": {
        "value": 9926290,
        "decimals": 6
      },
      "message": "I approve the transfer of 10 USDK from ARB to 5FHwkrdxkjF7xoL2ncGh4AEYs1KyJzz5MeiaHGz8h8GA on SOL."
    }
  },
  "peggedTo": "USD",
  "expiration": "2025-05-07T00:24:24Z"
}
```

If you need the raw fee-calculation API instead of the backend wrapper, the backend currently calls the fee service at `POST {{baseUrl}}/v3/fees/calculate`. For most integrations, `GET /submit/fees` remains the recommended entry point.
