# Offline Signer

## Sign transactions on your own servers

An MIT-licensed package that signs EVM, UTXO, Tron, XRP, Kaspa and Solana transactions locally. No API call, no API key, no network round trip — the private key stays in your process, because it never has a reason to leave it.

- MIT licensed
- Six chain families
- Zero API keys

## Why signing belongs on your side

A provider that can sign for you is a provider that can move your funds — and one whose breach becomes your breach. Splitting the work is what removes that: we prepare the transaction and broadcast it, you sign it.

- **No custody risk** — we never hold your keys, so there is nothing of yours for us to lose. Your security posture does not inherit ours.
- **Simpler compliance** — many licences and audits turn on who controls the keys. Keeping them in your own infrastructure keeps that answer short.
- **No lock-in** — the package is MIT and works standalone. If you stop using our APIs tomorrow, your signing code keeps working.

## Where it sits in the flow

Three steps, and only the middle one touches a key. Prepare and broadcast are ordinary REST calls; signing happens in your process, offline.

1. `POST /prepare-transactions/…` returns an unsigned transaction
2. Sign it here, offline, with your key — no network call
3. `POST /broadcast-transactions/…` puts it on chain

### Broadcast

```json
{
  "data": {
    "item": {
      "signedTransactionHex": "0xf86607…"
    }
  }
}
```

### Response

```json
{
  "data": {
    "item": {
      "transactionId": "0x9f2b…"
    }
  }
}
```

## The whole integration

Install it, import the family you need, and sign. There is no client to configure and nothing to authenticate against.

```bash
npm i @cryptoapis-io/offline-signer
```

```javascript
import { evmSignFromDetails } from "@cryptoapis-io/offline-signer/evm";

// data.item from POST /prepare-transactions/evm/ethereum/mainnet/native-coins
const { signedTransactionHex } = await evmSignFromDetails({
  blockchain: "ethereum",
  network: "mainnet",
  privateKey: process.env.PRIVATE_KEY, // never leaves this process
  toAddress: item.recipient,
  value: item.value,
  nonce: item.nonce,
  gasLimit: item.gasLimit,
});

// hand signedTransactionHex to POST /broadcast-transactions
```

## Chains it signs

Six families, one import path each, so signing EVM never pulls in the Bitcoin, Zcash or Solana stacks. Every chain signs differently — this is the part you would otherwise maintain yourself.

| Family | Blockchains | Import |
| --- | --- | --- |
| EVM | Ethereum, Ethereum Classic, BNB Smart Chain, Polygon, Avalanche, Arbitrum, Base, Optimism, Tron (EVM) | `/evm` |
| UTXO | Bitcoin, Bitcoin Cash, Litecoin, Dogecoin, Dash, Zcash | `/utxo` |
| Tron | Native TRX and TRC transactions | `/tron` |
| XRP | XRP Ledger payments | `/xrp` |
| Kaspa | Native Kaspa signing | `/kaspa` |
| Solana | Partial / fee-payer signing | `/solana` |

## Read the signing docs

Per-family signatures, the fields each one expects, and what it returns.

[developers.cryptoapis.io](https://developers.cryptoapis.io/)

## Frequently asked questions

**Does my private key ever reach Crypto APIs?**
No. The package runs entirely inside your own process — no API call, no API key,
no network round trip. The key is used locally to produce a signed transaction
hex and never leaves your infrastructure.

**Which blockchains can the offline signer sign for?**
EVM chains, UTXO chains, Tron, XRP, Kaspa and Solana. Each family has its own
entry point, so you only pull in the code for the chains you use.

**How much does signing cost in credits?**
Nothing. Signing happens in your process and never reaches our gateway, so there
is no request to charge for. You are billed only for preparing and broadcasting.

**How does the signer fit with the rest of the API?**
`POST /prepare-transactions` → sign locally → `POST /broadcast-transactions`.

**Is the offline signer open source?**
Yes — `@cryptoapis-io/offline-signer` on npm, MIT licensed.

**Do I need a Crypto APIs account to use it?**
Not for signing; the package needs no API key. You need one for the surrounding
calls that talk to the blockchain.
