# Signers

> Load the operator wallet that fee-pays and settles payments — local keypairs or remote signing backends — via the Signer factory.

The operator signer fee-pays and co-signs settlement. Pass it as `operator.signer` to `createPayKit`. Key handling is built on [Solana Keychain](https://www.npmjs.com/package/@solana/keychain): local constructors ride on `@solana/keychain-memory`, and remote backends plug in through `Signer.from`.

## Local key material

```ts
import { Signer } from '@solana/pay-kit';

const fromFile = await Signer.file('config/operator.json'); // Solana CLI JSON keypair
const fromEnv = await Signer.env('OPERATOR_KEY'); // JSON / hex / base58, auto-detected
const ephemeral = await Signer.generate(); // a fresh key, for tests

const pay = await createPayKit({
  network: 'devnet',
  operator: { signer: fromFile, recipient: MERCHANT },
  pricing: { report: usd('0.10') },
});
```

## Remote signing

For AWS KMS, GCP KMS, Vault, Privy, Turnkey, and other backends, build a keychain signer and wrap it with `Signer.from`:

```ts
import { Signer } from '@solana/pay-kit';
import { createKeychainSigner } from '@solana/keychain';

const remote = Signer.from(await createKeychainSigner({ backend: 'vault' /* … */ }), { feePayer: false });
```

## The demo signer

`Signer.demo()` is a published keypair that is byte-for-byte identical across the Ruby, Python, PHP, and Lua SDKs, so processes running different SDKs can exchange traffic during local development. It is the zero-config default recipient on localnet.

It is **public by design** and refused on mainnet at boot — `solana_mainnet` plus the demo signer throws [`DemoSignerOnMainnetError`](/docs/sdk/typescript/errors) so real funds never route to a known address by accident.
