# GCP KMS Signer

> Sign Sui transactions with a key stored in Google Cloud Key Management Service

The `GcpKmsSigner` signs Sui transactions using a key held in
[Google Cloud KMS](https://cloud.google.com/kms). The private key never leaves GCP; the signer sends
the message digest to KMS and receives the signature back.

GCP KMS supports the `Secp256k1` and `Secp256r1` schemes. The curve of the KMS key determines the
signature scheme (`EC_SIGN_SECP256K1_SHA256` → `Secp256k1`, `EC_SIGN_P256_SHA256` → `Secp256r1`).

## Installation

```sh npm2yarn
npm i @mysten/gcp-kms-signer
```

## Creating a signer

Construct the signer with `GcpKmsSigner.fromOptions`, identifying the key by its project, location,
key ring, key, and version. This is async: it fetches the public key from KMS so the signer can
derive the Sui address.

```typescript

const signer = await GcpKmsSigner.fromOptions({
	projectId: 'your-google-project-id',
	location: 'your-google-location',
	keyRing: 'your-google-keyring',
	cryptoKey: 'your-google-key-name',
	cryptoKeyVersion: 'your-google-key-version',
});
```

### Parameters

`fromOptions(options)`

| Parameter          | Type     | Description           |
| ------------------ | -------- | --------------------- |
| `projectId`        | `string` | The GCP project ID    |
| `location`         | `string` | The GCP location      |
| `keyRing`          | `string` | The GCP key ring name |
| `cryptoKey`        | `string` | The GCP key name      |
| `cryptoKeyVersion` | `string` | The GCP key version   |

If you already have a fully-qualified KMS version name, construct the signer directly with
`GcpKmsSigner.fromVersionName`:

```typescript
const signer = await GcpKmsSigner.fromVersionName(
	'projects/p/locations/l/keyRings/r/cryptoKeys/k/cryptoKeyVersions/1',
);
```

## Usage

Once created, the signer behaves like any other [`Signer`](/sui/cryptography): derive the address,
sign messages, and sign or execute transactions.

```typescript
// Derive the Sui address
const address = signer.getPublicKey().toSuiAddress();

// Sign a personal message
const message = new TextEncoder().encode('Hello, GCP KMS Signer!');
const { signature } = await signer.signPersonalMessage(message);

// Verify the signature
const isValid = await signer.getPublicKey().verifyPersonalMessage(message, signature);
console.log(isValid); // true
```

To sign and submit a transaction, pass the signer to a client:

```typescript

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.sui.io:443',
});

const result = await client.signAndExecuteTransaction({ transaction, signer });
if (result.FailedTransaction) {
	throw new Error('Transaction failed to execute');
}
console.log(result.Transaction.digest);
```

See [Cryptography](/sui/cryptography) for the full signing and verification API shared by all
signers.