@solana/keychain-aws-kms 0.0.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -0
- package/dist/__tests__/aws-kms-signer.test.d.ts +2 -0
- package/dist/__tests__/aws-kms-signer.test.d.ts.map +1 -0
- package/dist/__tests__/aws-kms-signer.test.js +333 -0
- package/dist/__tests__/aws-kms-signer.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +3 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +5 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/aws-kms-signer.d.ts +52 -0
- package/dist/aws-kms-signer.d.ts.map +1 -0
- package/dist/aws-kms-signer.js +174 -0
- package/dist/aws-kms-signer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -9
- package/src/__tests__/aws-kms-signer.test.ts +425 -0
- package/src/__tests__/setup.ts +5 -0
- package/src/aws-kms-signer.ts +214 -0
- package/src/index.ts +2 -0
- package/src/types.ts +40 -0
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @solana/keychain-aws-kms
|
|
2
|
+
|
|
3
|
+
AWS KMS-based signer for Solana transactions using EdDSA (Ed25519) signing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @solana/keychain-aws-kms @aws-sdk/client-kms
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
1. An AWS KMS key with:
|
|
14
|
+
- **Key spec**: `ECC_NIST_EDWARDS25519`
|
|
15
|
+
- **Key usage**: `SIGN_VERIFY`
|
|
16
|
+
|
|
17
|
+
2. AWS credentials configured (see [AWS Credentials](#aws-credentials) below)
|
|
18
|
+
|
|
19
|
+
## AWS Credentials
|
|
20
|
+
|
|
21
|
+
The signer uses the **AWS default credential provider chain** to authenticate. You don't need to pass credentials explicitly unless you want to override the defaults.
|
|
22
|
+
|
|
23
|
+
### Credential Resolution Order
|
|
24
|
+
|
|
25
|
+
The AWS SDK looks for credentials in this order:
|
|
26
|
+
|
|
27
|
+
1. **Environment variables**
|
|
28
|
+
```bash
|
|
29
|
+
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
|
|
30
|
+
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
|
31
|
+
export AWS_SESSION_TOKEN="..." # Optional, for temporary credentials
|
|
32
|
+
export AWS_REGION="us-east-1" # Optional
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
2. **Shared credentials file** (`~/.aws/credentials`)
|
|
36
|
+
```ini
|
|
37
|
+
[default]
|
|
38
|
+
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
|
|
39
|
+
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
3. **IAM role** (automatic when running on AWS EC2, ECS, or Lambda)
|
|
43
|
+
|
|
44
|
+
4. **Web identity token** (for EKS/Kubernetes with IRSA)
|
|
45
|
+
|
|
46
|
+
### Recommended Setup
|
|
47
|
+
|
|
48
|
+
| Environment | Recommended Method |
|
|
49
|
+
|-------------|-------------------|
|
|
50
|
+
| **Production on AWS** | IAM role attached to EC2/ECS/Lambda (no explicit creds needed) |
|
|
51
|
+
| **Local development** | Environment variables or `~/.aws/credentials` file |
|
|
52
|
+
| **CI/CD pipelines** | Environment variables or OIDC |
|
|
53
|
+
| **Explicit control** | Pass `credentials` in config (TypeScript only) |
|
|
54
|
+
|
|
55
|
+
### Security Best Practices
|
|
56
|
+
|
|
57
|
+
- **Never commit credentials** to source control
|
|
58
|
+
- **Use IAM roles** in production instead of long-lived access keys
|
|
59
|
+
- **Use least-privilege IAM policies** - only grant `kms:Sign` and `kms:DescribeKey`
|
|
60
|
+
- **Enable CloudTrail** to audit KMS key usage
|
|
61
|
+
|
|
62
|
+
## Creating an AWS KMS Key
|
|
63
|
+
|
|
64
|
+
Use the AWS CLI to create a key suitable for Solana signing:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
aws kms create-key \
|
|
68
|
+
--key-spec ECC_NIST_EDWARDS25519 \
|
|
69
|
+
--key-usage SIGN_VERIFY \
|
|
70
|
+
--description "Solana signing key"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Or use the AWS Console:
|
|
74
|
+
1. Go to AWS KMS → Customer managed keys
|
|
75
|
+
2. Click "Create key"
|
|
76
|
+
3. Select "Asymmetric" key type
|
|
77
|
+
4. Select "ECC_NIST_EDWARDS25519" key spec
|
|
78
|
+
5. Select "Sign and verify" key usage
|
|
79
|
+
6. Complete the key creation process
|
|
80
|
+
|
|
81
|
+
## Usage
|
|
82
|
+
|
|
83
|
+
### Basic Example
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { AwsKmsSigner } from '@solana/keychain-aws-kms';
|
|
87
|
+
|
|
88
|
+
const signer = new AwsKmsSigner({
|
|
89
|
+
keyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
|
|
90
|
+
publicKey: 'YourSolanaPublicKeyBase58',
|
|
91
|
+
region: 'us-east-1', // Optional, defaults to AWS config default
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Sign a message
|
|
95
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]) };
|
|
96
|
+
const signatures = await signer.signMessages([message]);
|
|
97
|
+
|
|
98
|
+
// Sign a transaction
|
|
99
|
+
const signatures = await signer.signTransactions([transaction]);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### With Custom Credentials
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const signer = new AwsKmsSigner({
|
|
106
|
+
keyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
|
|
107
|
+
publicKey: 'YourSolanaPublicKeyBase58',
|
|
108
|
+
region: 'us-east-1',
|
|
109
|
+
credentials: {
|
|
110
|
+
accessKeyId: 'your-access-key-id',
|
|
111
|
+
secretAccessKey: 'your-secret-access-key',
|
|
112
|
+
sessionToken: 'optional-session-token', // For temporary credentials
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### With Request Delay (Rate Limiting)
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const signer = new AwsKmsSigner({
|
|
121
|
+
keyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
|
|
122
|
+
publicKey: 'YourSolanaPublicKeyBase58',
|
|
123
|
+
requestDelayMs: 100, // 100ms delay between concurrent requests
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## API Reference
|
|
128
|
+
|
|
129
|
+
### `AwsKmsSigner`
|
|
130
|
+
|
|
131
|
+
#### Constructor
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
new AwsKmsSigner(config: AwsKmsSignerConfig)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Config Options:**
|
|
138
|
+
- `keyId` (required): AWS KMS key ID or ARN
|
|
139
|
+
- `publicKey` (required): Solana public key (base58-encoded)
|
|
140
|
+
- `region` (optional): AWS region (defaults to AWS config default)
|
|
141
|
+
- `requestDelayMs` (optional): Delay in ms between concurrent requests (default: 0)
|
|
142
|
+
- `credentials` (optional): AWS credentials object
|
|
143
|
+
|
|
144
|
+
#### Methods
|
|
145
|
+
|
|
146
|
+
- `signMessages(messages)`: Sign multiple messages
|
|
147
|
+
- `signTransactions(transactions)`: Sign multiple transactions
|
|
148
|
+
- `isAvailable()`: Check if the signer is available and the key is valid
|
|
149
|
+
|
|
150
|
+
## AWS IAM Permissions
|
|
151
|
+
|
|
152
|
+
The AWS credentials used must have the following permissions:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"Version": "2012-10-17",
|
|
157
|
+
"Statement": [
|
|
158
|
+
{
|
|
159
|
+
"Effect": "Allow",
|
|
160
|
+
"Action": [
|
|
161
|
+
"kms:Sign",
|
|
162
|
+
"kms:DescribeKey"
|
|
163
|
+
],
|
|
164
|
+
"Resource": "arn:aws:kms:*:*:key/*"
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Notes
|
|
171
|
+
|
|
172
|
+
- Ed25519 signatures are 64 bytes
|
|
173
|
+
- The signer uses `ED25519_SHA_512` algorithm with `RAW` message type
|
|
174
|
+
- The key must be in `Enabled` state to sign
|
|
175
|
+
- Rate limiting can be configured via `requestDelayMs` to avoid AWS KMS throttling
|
|
176
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws-kms-signer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/aws-kms-signer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { generateKeyPairSigner } from '@solana/signers';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { assertIsSolanaSigner } from '@solana/keychain-core';
|
|
4
|
+
import { AwsKmsSigner } from '../aws-kms-signer.js';
|
|
5
|
+
// Mock AWS SDK
|
|
6
|
+
const mockSend = vi.fn();
|
|
7
|
+
vi.mock('@aws-sdk/client-kms', () => {
|
|
8
|
+
// Create proper constructor mock classes
|
|
9
|
+
class MockKMSClient {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.send = mockSend;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class MockSignCommand {
|
|
15
|
+
constructor(params) {
|
|
16
|
+
this.input = params;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
class MockDescribeKeyCommand {
|
|
20
|
+
constructor(params) {
|
|
21
|
+
this.input = params;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
KMSClient: MockKMSClient,
|
|
26
|
+
SignCommand: MockSignCommand,
|
|
27
|
+
DescribeKeyCommand: MockDescribeKeyCommand,
|
|
28
|
+
MessageType: {
|
|
29
|
+
RAW: 'RAW',
|
|
30
|
+
DIGEST: 'DIGEST',
|
|
31
|
+
},
|
|
32
|
+
SigningAlgorithmSpec: {
|
|
33
|
+
ED25519_SHA_512: 'ED25519_SHA_512',
|
|
34
|
+
ED25519_PH_SHA_512: 'ED25519_PH_SHA_512',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
describe('AwsKmsSigner', () => {
|
|
39
|
+
const TEST_KEY_ID = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012';
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
vi.clearAllMocks();
|
|
42
|
+
});
|
|
43
|
+
describe('constructor', () => {
|
|
44
|
+
it('creates an AwsKmsSigner with valid config', async () => {
|
|
45
|
+
const keyPair = await generateKeyPairSigner();
|
|
46
|
+
const config = {
|
|
47
|
+
keyId: TEST_KEY_ID,
|
|
48
|
+
publicKey: keyPair.address,
|
|
49
|
+
};
|
|
50
|
+
const signer = new AwsKmsSigner(config);
|
|
51
|
+
expect(signer.address).toBe(keyPair.address);
|
|
52
|
+
assertIsSolanaSigner(signer);
|
|
53
|
+
expect(signer.signMessages).toBeDefined();
|
|
54
|
+
expect(signer.signTransactions).toBeDefined();
|
|
55
|
+
expect(signer.isAvailable).toBeDefined();
|
|
56
|
+
});
|
|
57
|
+
it('sets address field correctly from config', async () => {
|
|
58
|
+
const keyPair = await generateKeyPairSigner();
|
|
59
|
+
const config = {
|
|
60
|
+
keyId: TEST_KEY_ID,
|
|
61
|
+
publicKey: keyPair.address,
|
|
62
|
+
};
|
|
63
|
+
const signer = new AwsKmsSigner(config);
|
|
64
|
+
expect(signer.address).toBe(keyPair.address);
|
|
65
|
+
});
|
|
66
|
+
it('should throw error for missing keyId', async () => {
|
|
67
|
+
const keyPair = await generateKeyPairSigner();
|
|
68
|
+
expect(() => {
|
|
69
|
+
new AwsKmsSigner({
|
|
70
|
+
keyId: '',
|
|
71
|
+
publicKey: keyPair.address,
|
|
72
|
+
});
|
|
73
|
+
}).toThrow('Missing required keyId field');
|
|
74
|
+
});
|
|
75
|
+
it('should throw error for missing publicKey', () => {
|
|
76
|
+
expect(() => {
|
|
77
|
+
new AwsKmsSigner({
|
|
78
|
+
keyId: TEST_KEY_ID,
|
|
79
|
+
publicKey: '',
|
|
80
|
+
});
|
|
81
|
+
}).toThrow('Missing required publicKey field');
|
|
82
|
+
});
|
|
83
|
+
it('should throw error for invalid public key', () => {
|
|
84
|
+
expect(() => {
|
|
85
|
+
new AwsKmsSigner({
|
|
86
|
+
keyId: TEST_KEY_ID,
|
|
87
|
+
publicKey: 'invalid-key',
|
|
88
|
+
});
|
|
89
|
+
}).toThrow('Invalid Solana public key format');
|
|
90
|
+
});
|
|
91
|
+
it('should validate requestDelayMs', async () => {
|
|
92
|
+
const keyPair = await generateKeyPairSigner();
|
|
93
|
+
expect(() => {
|
|
94
|
+
new AwsKmsSigner({
|
|
95
|
+
keyId: TEST_KEY_ID,
|
|
96
|
+
publicKey: keyPair.address,
|
|
97
|
+
requestDelayMs: -1,
|
|
98
|
+
});
|
|
99
|
+
}).toThrow('requestDelayMs must not be negative');
|
|
100
|
+
});
|
|
101
|
+
it('should warn for high requestDelayMs', async () => {
|
|
102
|
+
const keyPair = await generateKeyPairSigner();
|
|
103
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
104
|
+
new AwsKmsSigner({
|
|
105
|
+
keyId: TEST_KEY_ID,
|
|
106
|
+
publicKey: keyPair.address,
|
|
107
|
+
requestDelayMs: 5000,
|
|
108
|
+
});
|
|
109
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('requestDelayMs is greater than 3000ms'));
|
|
110
|
+
warnSpy.mockRestore();
|
|
111
|
+
});
|
|
112
|
+
it('should accept region configuration', async () => {
|
|
113
|
+
const keyPair = await generateKeyPairSigner();
|
|
114
|
+
const signer = new AwsKmsSigner({
|
|
115
|
+
keyId: TEST_KEY_ID,
|
|
116
|
+
publicKey: keyPair.address,
|
|
117
|
+
region: 'us-west-2',
|
|
118
|
+
});
|
|
119
|
+
expect(signer).toBeDefined();
|
|
120
|
+
});
|
|
121
|
+
it('should accept credentials configuration', async () => {
|
|
122
|
+
const keyPair = await generateKeyPairSigner();
|
|
123
|
+
const signer = new AwsKmsSigner({
|
|
124
|
+
keyId: TEST_KEY_ID,
|
|
125
|
+
publicKey: keyPair.address,
|
|
126
|
+
credentials: {
|
|
127
|
+
accessKeyId: 'test-access-key',
|
|
128
|
+
secretAccessKey: 'test-secret-key',
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
expect(signer).toBeDefined();
|
|
132
|
+
});
|
|
133
|
+
it('should accept session token in credentials', async () => {
|
|
134
|
+
const keyPair = await generateKeyPairSigner();
|
|
135
|
+
const signer = new AwsKmsSigner({
|
|
136
|
+
keyId: TEST_KEY_ID,
|
|
137
|
+
publicKey: keyPair.address,
|
|
138
|
+
credentials: {
|
|
139
|
+
accessKeyId: 'test-access-key',
|
|
140
|
+
secretAccessKey: 'test-secret-key',
|
|
141
|
+
sessionToken: 'test-session-token',
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
expect(signer).toBeDefined();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe('signMessages', () => {
|
|
148
|
+
it('should sign a message successfully', async () => {
|
|
149
|
+
const keyPair = await generateKeyPairSigner();
|
|
150
|
+
mockSend.mockResolvedValue({
|
|
151
|
+
Signature: new Uint8Array(64).fill(0x42),
|
|
152
|
+
});
|
|
153
|
+
const signer = new AwsKmsSigner({
|
|
154
|
+
keyId: TEST_KEY_ID,
|
|
155
|
+
publicKey: keyPair.address,
|
|
156
|
+
});
|
|
157
|
+
// Provide required 'signatures' property to satisfy the type
|
|
158
|
+
const message = {
|
|
159
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
160
|
+
signatures: {},
|
|
161
|
+
};
|
|
162
|
+
const result = await signer.signMessages([message]);
|
|
163
|
+
expect(result).toHaveLength(1);
|
|
164
|
+
expect(result[0]?.[signer.address]).toBeDefined();
|
|
165
|
+
expect(mockSend).toHaveBeenCalledTimes(1);
|
|
166
|
+
});
|
|
167
|
+
it('should handle multiple messages with delay', async () => {
|
|
168
|
+
const keyPair = await generateKeyPairSigner();
|
|
169
|
+
mockSend.mockResolvedValue({
|
|
170
|
+
Signature: new Uint8Array(64).fill(0x42),
|
|
171
|
+
});
|
|
172
|
+
const signer = new AwsKmsSigner({
|
|
173
|
+
keyId: TEST_KEY_ID,
|
|
174
|
+
publicKey: keyPair.address,
|
|
175
|
+
requestDelayMs: 10,
|
|
176
|
+
});
|
|
177
|
+
const messages = [
|
|
178
|
+
{ content: new Uint8Array([1]) },
|
|
179
|
+
{ content: new Uint8Array([2]) },
|
|
180
|
+
{ content: new Uint8Array([3]) },
|
|
181
|
+
];
|
|
182
|
+
// Add missing 'signatures' property for each message to satisfy the type requirement
|
|
183
|
+
const messagesWithSignatures = messages.map(msg => ({
|
|
184
|
+
...msg,
|
|
185
|
+
signatures: {},
|
|
186
|
+
}));
|
|
187
|
+
const startTime = Date.now();
|
|
188
|
+
const result = await signer.signMessages(messagesWithSignatures);
|
|
189
|
+
const endTime = Date.now();
|
|
190
|
+
expect(result).toHaveLength(3);
|
|
191
|
+
expect(mockSend).toHaveBeenCalledTimes(3);
|
|
192
|
+
// Should have some delay (at least 15ms for 2 delays of 10ms each)
|
|
193
|
+
expect(endTime - startTime).toBeGreaterThanOrEqual(15);
|
|
194
|
+
});
|
|
195
|
+
it('should throw error on invalid signature length', async () => {
|
|
196
|
+
const keyPair = await generateKeyPairSigner();
|
|
197
|
+
mockSend.mockResolvedValue({
|
|
198
|
+
Signature: new Uint8Array(32), // Wrong length
|
|
199
|
+
});
|
|
200
|
+
const signer = new AwsKmsSigner({
|
|
201
|
+
keyId: TEST_KEY_ID,
|
|
202
|
+
publicKey: keyPair.address,
|
|
203
|
+
});
|
|
204
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
205
|
+
await expect(signer.signMessages([message])).rejects.toThrow('Invalid signature length');
|
|
206
|
+
});
|
|
207
|
+
it('should throw error on missing signature', async () => {
|
|
208
|
+
const keyPair = await generateKeyPairSigner();
|
|
209
|
+
mockSend.mockResolvedValue({
|
|
210
|
+
Signature: undefined,
|
|
211
|
+
});
|
|
212
|
+
const signer = new AwsKmsSigner({
|
|
213
|
+
keyId: TEST_KEY_ID,
|
|
214
|
+
publicKey: keyPair.address,
|
|
215
|
+
});
|
|
216
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
217
|
+
await expect(signer.signMessages([message])).rejects.toThrow('No signature in AWS KMS response');
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
describe('signTransactions', () => {
|
|
221
|
+
it('should sign a transaction successfully', async () => {
|
|
222
|
+
const keyPair = await generateKeyPairSigner();
|
|
223
|
+
mockSend.mockResolvedValue({
|
|
224
|
+
Signature: new Uint8Array(64).fill(0x42),
|
|
225
|
+
});
|
|
226
|
+
const signer = new AwsKmsSigner({
|
|
227
|
+
keyId: TEST_KEY_ID,
|
|
228
|
+
publicKey: keyPair.address,
|
|
229
|
+
});
|
|
230
|
+
const transaction = {
|
|
231
|
+
messageBytes: new Uint8Array([1, 2, 3, 4]),
|
|
232
|
+
signatures: {},
|
|
233
|
+
};
|
|
234
|
+
const result = await signer.signTransactions([transaction]);
|
|
235
|
+
expect(result).toHaveLength(1);
|
|
236
|
+
expect(result[0]).toHaveProperty(signer.address);
|
|
237
|
+
expect(mockSend).toHaveBeenCalledTimes(1);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
describe('isAvailable', () => {
|
|
241
|
+
it('should return true for valid Ed25519 key', async () => {
|
|
242
|
+
const keyPair = await generateKeyPairSigner();
|
|
243
|
+
mockSend.mockResolvedValue({
|
|
244
|
+
KeyMetadata: {
|
|
245
|
+
KeyId: TEST_KEY_ID,
|
|
246
|
+
KeySpec: 'ECC_NIST_EDWARDS25519',
|
|
247
|
+
KeyUsage: 'SIGN_VERIFY',
|
|
248
|
+
KeyState: 'Enabled',
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
const signer = new AwsKmsSigner({
|
|
252
|
+
keyId: TEST_KEY_ID,
|
|
253
|
+
publicKey: keyPair.address,
|
|
254
|
+
});
|
|
255
|
+
const available = await signer.isAvailable();
|
|
256
|
+
expect(available).toBe(true);
|
|
257
|
+
});
|
|
258
|
+
it('should return false for wrong key spec', async () => {
|
|
259
|
+
const keyPair = await generateKeyPairSigner();
|
|
260
|
+
mockSend.mockResolvedValue({
|
|
261
|
+
KeyMetadata: {
|
|
262
|
+
KeyId: TEST_KEY_ID,
|
|
263
|
+
KeySpec: 'RSA_2048',
|
|
264
|
+
KeyUsage: 'SIGN_VERIFY',
|
|
265
|
+
KeyState: 'Enabled',
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
const signer = new AwsKmsSigner({
|
|
269
|
+
keyId: TEST_KEY_ID,
|
|
270
|
+
publicKey: keyPair.address,
|
|
271
|
+
});
|
|
272
|
+
const available = await signer.isAvailable();
|
|
273
|
+
expect(available).toBe(false);
|
|
274
|
+
});
|
|
275
|
+
it('should return false for wrong key usage', async () => {
|
|
276
|
+
const keyPair = await generateKeyPairSigner();
|
|
277
|
+
mockSend.mockResolvedValue({
|
|
278
|
+
KeyMetadata: {
|
|
279
|
+
KeyId: TEST_KEY_ID,
|
|
280
|
+
KeySpec: 'ECC_NIST_EDWARDS25519',
|
|
281
|
+
KeyUsage: 'ENCRYPT_DECRYPT',
|
|
282
|
+
KeyState: 'Enabled',
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
const signer = new AwsKmsSigner({
|
|
286
|
+
keyId: TEST_KEY_ID,
|
|
287
|
+
publicKey: keyPair.address,
|
|
288
|
+
});
|
|
289
|
+
const available = await signer.isAvailable();
|
|
290
|
+
expect(available).toBe(false);
|
|
291
|
+
});
|
|
292
|
+
it('should return false for disabled key', async () => {
|
|
293
|
+
const keyPair = await generateKeyPairSigner();
|
|
294
|
+
mockSend.mockResolvedValue({
|
|
295
|
+
KeyMetadata: {
|
|
296
|
+
KeyId: TEST_KEY_ID,
|
|
297
|
+
KeySpec: 'ECC_NIST_EDWARDS25519',
|
|
298
|
+
KeyUsage: 'SIGN_VERIFY',
|
|
299
|
+
KeyState: 'Disabled',
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
const signer = new AwsKmsSigner({
|
|
303
|
+
keyId: TEST_KEY_ID,
|
|
304
|
+
publicKey: keyPair.address,
|
|
305
|
+
});
|
|
306
|
+
const available = await signer.isAvailable();
|
|
307
|
+
expect(available).toBe(false);
|
|
308
|
+
});
|
|
309
|
+
it('should return false on error', async () => {
|
|
310
|
+
const keyPair = await generateKeyPairSigner();
|
|
311
|
+
mockSend.mockRejectedValue(new Error('AWS error'));
|
|
312
|
+
const signer = new AwsKmsSigner({
|
|
313
|
+
keyId: TEST_KEY_ID,
|
|
314
|
+
publicKey: keyPair.address,
|
|
315
|
+
});
|
|
316
|
+
const available = await signer.isAvailable();
|
|
317
|
+
expect(available).toBe(false);
|
|
318
|
+
});
|
|
319
|
+
it('should return false on missing metadata', async () => {
|
|
320
|
+
const keyPair = await generateKeyPairSigner();
|
|
321
|
+
mockSend.mockResolvedValue({
|
|
322
|
+
KeyMetadata: undefined,
|
|
323
|
+
});
|
|
324
|
+
const signer = new AwsKmsSigner({
|
|
325
|
+
keyId: TEST_KEY_ID,
|
|
326
|
+
publicKey: keyPair.address,
|
|
327
|
+
});
|
|
328
|
+
const available = await signer.isAvailable();
|
|
329
|
+
expect(available).toBe(false);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
//# sourceMappingURL=aws-kms-signer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws-kms-signer.test.js","sourceRoot":"","sources":["../../src/__tests__/aws-kms-signer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,gFAAgF,CAAC;AACzG,eAAO,MAAM,WAAW,cAAc,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Test setup for AWS KMS signer tests
|
|
2
|
+
// This file can be used for shared test utilities or setup
|
|
3
|
+
export const TEST_KEY_ID = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012';
|
|
4
|
+
export const TEST_REGION = 'us-east-1';
|
|
5
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,2DAA2D;AAE3D,MAAM,CAAC,MAAM,WAAW,GAAG,6EAA6E,CAAC;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Address } from '@solana/addresses';
|
|
2
|
+
import { SolanaSigner } from '@solana/keychain-core';
|
|
3
|
+
import { SignableMessage, SignatureDictionary } from '@solana/signers';
|
|
4
|
+
import { Transaction, TransactionWithinSizeLimit, TransactionWithLifetime } from '@solana/transactions';
|
|
5
|
+
import type { AwsKmsSignerConfig } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* AWS KMS-based signer using EdDSA (Ed25519) signing
|
|
8
|
+
*
|
|
9
|
+
* The AWS KMS key must be created with:
|
|
10
|
+
* - Key spec: ECC_NIST_EDWARDS25519
|
|
11
|
+
* - Key usage: SIGN_VERIFY
|
|
12
|
+
*
|
|
13
|
+
* Example AWS CLI command to create a key:
|
|
14
|
+
* ```bash
|
|
15
|
+
* aws kms create-key \
|
|
16
|
+
* --key-spec ECC_NIST_EDWARDS25519 \
|
|
17
|
+
* --key-usage SIGN_VERIFY \
|
|
18
|
+
* --description "Solana signing key"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class AwsKmsSigner<TAddress extends string = string> implements SolanaSigner<TAddress> {
|
|
22
|
+
readonly address: Address<TAddress>;
|
|
23
|
+
private readonly keyId;
|
|
24
|
+
private readonly client;
|
|
25
|
+
private readonly requestDelayMs;
|
|
26
|
+
constructor(config: AwsKmsSignerConfig);
|
|
27
|
+
/**
|
|
28
|
+
* Validate request delay ms
|
|
29
|
+
*/
|
|
30
|
+
private validateRequestDelayMs;
|
|
31
|
+
/**
|
|
32
|
+
* Add delay between concurrent requests
|
|
33
|
+
*/
|
|
34
|
+
private delay;
|
|
35
|
+
/**
|
|
36
|
+
* Sign message bytes using AWS KMS EdDSA signing
|
|
37
|
+
*/
|
|
38
|
+
private signBytes;
|
|
39
|
+
/**
|
|
40
|
+
* Sign multiple messages using AWS KMS
|
|
41
|
+
*/
|
|
42
|
+
signMessages(messages: readonly SignableMessage[]): Promise<readonly SignatureDictionary[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Sign multiple transactions using AWS KMS
|
|
45
|
+
*/
|
|
46
|
+
signTransactions(transactions: readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[]): Promise<readonly SignatureDictionary[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if AWS KMS is available and the key is accessible
|
|
49
|
+
*/
|
|
50
|
+
isAvailable(): Promise<boolean>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=aws-kms-signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws-kms-signer.d.ts","sourceRoot":"","sources":["../src/aws-kms-signer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAmB,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAA8C,YAAY,EAAoB,MAAM,uBAAuB,CAAC;AAEnH,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAExG,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,CAAE,YAAW,YAAY,CAAC,QAAQ,CAAC;IACzF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,MAAM,EAAE,kBAAkB;IA4CtC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAa9B;;OAEG;YACW,KAAK;IAMnB;;OAEG;YACW,SAAS;IA+CvB;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAiBjG;;OAEG;IACG,gBAAgB,CAClB,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,0BAA0B,GAAG,uBAAuB,CAAC,EAAE,GAC9F,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAc1C;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAsBxC"}
|