@solana/keychain-vault 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 +145 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +23 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/vault-signer.integration.test.d.ts +2 -0
- package/dist/__tests__/vault-signer.integration.test.d.ts.map +1 -0
- package/dist/__tests__/vault-signer.integration.test.js +17 -0
- package/dist/__tests__/vault-signer.integration.test.js.map +1 -0
- package/dist/__tests__/vault-signer.test.d.ts +2 -0
- package/dist/__tests__/vault-signer.test.d.ts.map +1 -0
- package/dist/__tests__/vault-signer.test.js +282 -0
- package/dist/__tests__/vault-signer.test.js.map +1 -0
- package/dist/index.d.ts +4 -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 +114 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vault-signer.d.ts +67 -0
- package/dist/vault-signer.d.ts.map +1 -0
- package/dist/vault-signer.js +196 -0
- package/dist/vault-signer.js.map +1 -0
- package/package.json +54 -9
- package/src/__tests__/setup.ts +26 -0
- package/src/__tests__/vault-signer.integration.test.ts +17 -0
- package/src/__tests__/vault-signer.test.ts +375 -0
- package/src/index.ts +11 -0
- package/src/types.ts +129 -0
- package/src/vault-signer.ts +255 -0
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# @solana/keychain-vault
|
|
2
|
+
|
|
3
|
+
HashiCorp Vault-based signer for Solana transactions using Vault's transit engine.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @solana/keychain-vault
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
1. A HashiCorp Vault instance with the transit engine enabled
|
|
14
|
+
2. An ED25519 key created in the transit engine
|
|
15
|
+
3. A Vault token with sign permissions for the key
|
|
16
|
+
|
|
17
|
+
### Creating a Transit Key in Vault
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Enable the transit engine
|
|
21
|
+
vault secrets enable transit
|
|
22
|
+
|
|
23
|
+
# Create an ED25519 key
|
|
24
|
+
vault write transit/keys/my-solana-key type=ed25519
|
|
25
|
+
|
|
26
|
+
# Export the public key to get your Solana address
|
|
27
|
+
vault read -field=keys transit/export/signing-key/my-solana-key/1
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Basic Setup
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { VaultSigner } from '@solana/keychain-vault';
|
|
36
|
+
|
|
37
|
+
const signer = new VaultSigner({
|
|
38
|
+
vaultAddr: 'https://vault.example.com',
|
|
39
|
+
vaultToken: 'hvs.your-vault-token',
|
|
40
|
+
keyName: 'my-solana-key',
|
|
41
|
+
publicKey: 'your-solana-public-key-base58', // Must match the Vault key
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Check if the signer is available
|
|
45
|
+
const isAvailable = await signer.isAvailable();
|
|
46
|
+
console.log('Vault signer available:', isAvailable);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Signing Transactions
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { pipe } from '@solana/functional';
|
|
53
|
+
import { createTransaction } from '@solana/transactions';
|
|
54
|
+
import { signTransaction } from '@solana/signers';
|
|
55
|
+
|
|
56
|
+
// Create your transaction
|
|
57
|
+
const transaction = pipe(
|
|
58
|
+
createTransaction({ version: 0 }),
|
|
59
|
+
// ... add instructions
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Sign the transaction
|
|
63
|
+
const signedTransaction = await signTransaction([signer], transaction);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Signing Messages
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { signMessage } from '@solana/signers';
|
|
70
|
+
|
|
71
|
+
const message = new TextEncoder().encode('Hello, Solana!');
|
|
72
|
+
const signature = await signMessage([signer], message);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### With Rate Limiting
|
|
76
|
+
|
|
77
|
+
If you're signing multiple transactions/messages concurrently and want to avoid rate limits:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const signer = new VaultSigner({
|
|
81
|
+
vaultAddr: 'https://vault.example.com',
|
|
82
|
+
vaultToken: 'hvs.your-vault-token',
|
|
83
|
+
keyName: 'my-solana-key',
|
|
84
|
+
publicKey: 'your-solana-public-key',
|
|
85
|
+
requestDelayMs: 100, // 100ms delay between concurrent requests
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### VaultSignerConfig
|
|
92
|
+
|
|
93
|
+
| Field | Type | Required | Description |
|
|
94
|
+
|-------|------|----------|-------------|
|
|
95
|
+
| `vaultAddr` | `string` | Yes | Vault server address (e.g., https://vault.example.com) |
|
|
96
|
+
| `vaultToken` | `string` | Yes | Vault authentication token |
|
|
97
|
+
| `keyName` | `string` | Yes | Name of the transit key in Vault |
|
|
98
|
+
| `publicKey` | `string` | Yes | Solana public key (base58) corresponding to the Vault key |
|
|
99
|
+
| `requestDelayMs` | `number` | No | Delay in ms between concurrent signing requests (default: 0) |
|
|
100
|
+
|
|
101
|
+
## Vault Permissions
|
|
102
|
+
|
|
103
|
+
The Vault token must have the following permissions on the transit key:
|
|
104
|
+
|
|
105
|
+
```hcl
|
|
106
|
+
path "transit/sign/my-solana-key" {
|
|
107
|
+
capabilities = ["update"]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
path "transit/keys/my-solana-key" {
|
|
111
|
+
capabilities = ["read"]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Error Handling
|
|
116
|
+
|
|
117
|
+
The signer will throw errors with specific codes from `@solana/keychain-core`:
|
|
118
|
+
|
|
119
|
+
- `CONFIG_ERROR` - Invalid configuration
|
|
120
|
+
- `HTTP_ERROR` - Network request failed
|
|
121
|
+
- `REMOTE_API_ERROR` - Vault API returned an error
|
|
122
|
+
- `PARSING_ERROR` - Failed to parse Vault response
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { SignerErrorCode } from '@solana/keychain-core';
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
await signer.signMessages([message]);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (error.code === SignerErrorCode.REMOTE_API_ERROR) {
|
|
131
|
+
console.error('Vault API error:', error.message);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Security Considerations
|
|
137
|
+
|
|
138
|
+
1. **Token Security**: Never hardcode Vault tokens. Use environment variables or secure secret management.
|
|
139
|
+
2. **TLS**: Always use HTTPS when connecting to Vault.
|
|
140
|
+
3. **Token Rotation**: Implement token rotation and use short-lived tokens when possible.
|
|
141
|
+
4. **Audit Logging**: Enable Vault audit logging to track signing operations.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmB9C,wBAAsB,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAKjG"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VaultSigner } from '../vault-signer';
|
|
2
|
+
const SIGNER_TYPE = 'vault';
|
|
3
|
+
const REQUIRED_ENV_VARS = ['VAULT_ADDR', 'VAULT_TOKEN', 'VAULT_KEY_NAME', 'VAULT_SIGNER_PUBKEY'];
|
|
4
|
+
async function createVaultSigner() {
|
|
5
|
+
return new VaultSigner({
|
|
6
|
+
vaultAddr: process.env.VAULT_ADDR,
|
|
7
|
+
vaultToken: process.env.VAULT_TOKEN,
|
|
8
|
+
keyName: process.env.VAULT_KEY_NAME,
|
|
9
|
+
publicKey: process.env.VAULT_SIGNER_PUBKEY,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
const CONFIG = {
|
|
13
|
+
signerType: SIGNER_TYPE,
|
|
14
|
+
requiredEnvVars: REQUIRED_ENV_VARS,
|
|
15
|
+
createSigner: createVaultSigner,
|
|
16
|
+
};
|
|
17
|
+
export async function getConfig(scenarios) {
|
|
18
|
+
return {
|
|
19
|
+
...CONFIG,
|
|
20
|
+
testScenarios: scenarios,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,CAAC,CAAC;AAEjG,KAAK,UAAU,iBAAiB;IAC5B,OAAO,IAAI,WAAW,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;QAClC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,WAAY;QACpC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAe;QACpC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAoB;KAC9C,CAAC,CAAC;AACP,CAAC;AACD,MAAM,MAAM,GAAkC;IAC1C,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;CAClC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAyB;IACrD,OAAO;QACH,GAAG,MAAM;QACT,aAAa,EAAE,SAAS;KAC3B,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-signer.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vault-signer.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it } from 'vitest';
|
|
2
|
+
import { runSignerIntegrationTest } from '@solana/keychain-test-utils';
|
|
3
|
+
import { getConfig } from './setup';
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
config();
|
|
6
|
+
describe('VaultSigner Integration', () => {
|
|
7
|
+
it.skipIf(!process.env.VAULT_ADDR)('signs transactions with real API', async () => {
|
|
8
|
+
await runSignerIntegrationTest(await getConfig(['signTransaction']));
|
|
9
|
+
});
|
|
10
|
+
it.skipIf(!process.env.VAULT_ADDR)('signs messages with real API', async () => {
|
|
11
|
+
await runSignerIntegrationTest(await getConfig(['signMessage']));
|
|
12
|
+
});
|
|
13
|
+
it.skipIf(!process.env.VAULT_ADDR)('simulates transactions with real API', async () => {
|
|
14
|
+
await runSignerIntegrationTest(await getConfig(['simulateTransaction']));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=vault-signer.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-signer.integration.test.js","sourceRoot":"","sources":["../../src/__tests__/vault-signer.integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,MAAM,EAAE,CAAC;AAET,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-signer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vault-signer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { VaultSigner } from '../vault-signer.js';
|
|
3
|
+
// Mock fetch globally
|
|
4
|
+
global.fetch = vi.fn();
|
|
5
|
+
describe('VaultSigner', () => {
|
|
6
|
+
const mockConfig = {
|
|
7
|
+
keyName: 'test-key',
|
|
8
|
+
publicKey: '11111111111111111111111111111111',
|
|
9
|
+
vaultAddr: 'https://vault.example.com',
|
|
10
|
+
vaultToken: 'test-token',
|
|
11
|
+
};
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
vi.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
describe('constructor', () => {
|
|
16
|
+
it('should create a signer with valid configuration', () => {
|
|
17
|
+
const signer = new VaultSigner(mockConfig);
|
|
18
|
+
expect(signer.address).toBe(mockConfig.publicKey);
|
|
19
|
+
});
|
|
20
|
+
it('should throw error for missing vaultAddr', () => {
|
|
21
|
+
expect(() => {
|
|
22
|
+
new VaultSigner({
|
|
23
|
+
...mockConfig,
|
|
24
|
+
vaultAddr: '',
|
|
25
|
+
});
|
|
26
|
+
}).toThrow('Missing required configuration fields');
|
|
27
|
+
});
|
|
28
|
+
it('should throw error for missing vaultToken', () => {
|
|
29
|
+
expect(() => {
|
|
30
|
+
new VaultSigner({
|
|
31
|
+
...mockConfig,
|
|
32
|
+
vaultToken: '',
|
|
33
|
+
});
|
|
34
|
+
}).toThrow('Missing required configuration fields');
|
|
35
|
+
});
|
|
36
|
+
it('should throw error for missing keyName', () => {
|
|
37
|
+
expect(() => {
|
|
38
|
+
new VaultSigner({
|
|
39
|
+
...mockConfig,
|
|
40
|
+
keyName: '',
|
|
41
|
+
});
|
|
42
|
+
}).toThrow('Missing required configuration fields');
|
|
43
|
+
});
|
|
44
|
+
it('should throw error for invalid public key', () => {
|
|
45
|
+
expect(() => {
|
|
46
|
+
new VaultSigner({
|
|
47
|
+
...mockConfig,
|
|
48
|
+
publicKey: 'invalid-key',
|
|
49
|
+
});
|
|
50
|
+
}).toThrow('Invalid Solana public key format');
|
|
51
|
+
});
|
|
52
|
+
it('should remove trailing slash from vaultAddr', () => {
|
|
53
|
+
const signer = new VaultSigner({
|
|
54
|
+
...mockConfig,
|
|
55
|
+
vaultAddr: 'https://vault.example.com/',
|
|
56
|
+
});
|
|
57
|
+
expect(signer['vaultAddr']).toBe('https://vault.example.com');
|
|
58
|
+
});
|
|
59
|
+
it('should validate requestDelayMs', () => {
|
|
60
|
+
expect(() => {
|
|
61
|
+
new VaultSigner({
|
|
62
|
+
...mockConfig,
|
|
63
|
+
requestDelayMs: -1,
|
|
64
|
+
});
|
|
65
|
+
}).toThrow('requestDelayMs must not be negative');
|
|
66
|
+
});
|
|
67
|
+
it('should warn for high requestDelayMs', () => {
|
|
68
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
69
|
+
new VaultSigner({
|
|
70
|
+
...mockConfig,
|
|
71
|
+
requestDelayMs: 3001,
|
|
72
|
+
});
|
|
73
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('requestDelayMs is greater than 3000ms'));
|
|
74
|
+
warnSpy.mockRestore();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('isAvailable', () => {
|
|
78
|
+
it('should return true when Vault key is accessible and supports signing', async () => {
|
|
79
|
+
const mockResponse = {
|
|
80
|
+
data: {
|
|
81
|
+
supports_signing: true,
|
|
82
|
+
type: 'ed25519',
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
86
|
+
status: 200,
|
|
87
|
+
}));
|
|
88
|
+
const signer = new VaultSigner(mockConfig);
|
|
89
|
+
const result = await signer.isAvailable();
|
|
90
|
+
expect(result).toBe(true);
|
|
91
|
+
expect(fetch).toHaveBeenCalledWith('https://vault.example.com/v1/transit/keys/test-key', expect.objectContaining({
|
|
92
|
+
headers: {
|
|
93
|
+
'X-Vault-Token': 'test-token',
|
|
94
|
+
},
|
|
95
|
+
method: 'GET',
|
|
96
|
+
}));
|
|
97
|
+
});
|
|
98
|
+
it('should return false when Vault key does not support signing', async () => {
|
|
99
|
+
const mockResponse = {
|
|
100
|
+
data: {
|
|
101
|
+
supports_signing: false,
|
|
102
|
+
type: 'aes256-gcm96',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
106
|
+
status: 200,
|
|
107
|
+
}));
|
|
108
|
+
const signer = new VaultSigner(mockConfig);
|
|
109
|
+
const result = await signer.isAvailable();
|
|
110
|
+
expect(result).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
it('should return false when Vault key is not ed25519', async () => {
|
|
113
|
+
const mockResponse = {
|
|
114
|
+
data: {
|
|
115
|
+
supports_signing: true,
|
|
116
|
+
type: 'rsa-2048',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
120
|
+
status: 200,
|
|
121
|
+
}));
|
|
122
|
+
const signer = new VaultSigner(mockConfig);
|
|
123
|
+
const result = await signer.isAvailable();
|
|
124
|
+
expect(result).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
it('should return false when Vault returns error', async () => {
|
|
127
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response('{"errors":["permission denied"]}', {
|
|
128
|
+
status: 403,
|
|
129
|
+
}));
|
|
130
|
+
const signer = new VaultSigner(mockConfig);
|
|
131
|
+
const result = await signer.isAvailable();
|
|
132
|
+
expect(result).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
it('should return false when network request fails', async () => {
|
|
135
|
+
vi.mocked(fetch).mockRejectedValueOnce(new Error('Network error'));
|
|
136
|
+
const signer = new VaultSigner(mockConfig);
|
|
137
|
+
const result = await signer.isAvailable();
|
|
138
|
+
expect(result).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('signMessages', () => {
|
|
142
|
+
it('should sign a message successfully', async () => {
|
|
143
|
+
const mockSignature = 'vault:v1:' + 'a'.repeat(86); // Base64 encoded signature
|
|
144
|
+
const mockResponse = {
|
|
145
|
+
data: {
|
|
146
|
+
signature: mockSignature,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
150
|
+
status: 200,
|
|
151
|
+
}));
|
|
152
|
+
const signer = new VaultSigner(mockConfig);
|
|
153
|
+
const message = {
|
|
154
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
155
|
+
signatures: {},
|
|
156
|
+
};
|
|
157
|
+
const [result] = await signer.signMessages([message]);
|
|
158
|
+
expect(result).toHaveProperty(mockConfig.publicKey);
|
|
159
|
+
expect(fetch).toHaveBeenCalledWith('https://vault.example.com/v1/transit/sign/test-key', expect.objectContaining({
|
|
160
|
+
body: expect.stringContaining('"input"'),
|
|
161
|
+
headers: {
|
|
162
|
+
'Content-Type': 'application/json',
|
|
163
|
+
'X-Vault-Token': 'test-token',
|
|
164
|
+
},
|
|
165
|
+
method: 'POST',
|
|
166
|
+
}));
|
|
167
|
+
});
|
|
168
|
+
it('should handle Vault API errors', async () => {
|
|
169
|
+
const mockErrorResponse = {
|
|
170
|
+
errors: ['key not found'],
|
|
171
|
+
};
|
|
172
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockErrorResponse), {
|
|
173
|
+
status: 404,
|
|
174
|
+
}));
|
|
175
|
+
const signer = new VaultSigner(mockConfig);
|
|
176
|
+
const message = {
|
|
177
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
178
|
+
signatures: {},
|
|
179
|
+
};
|
|
180
|
+
await expect(signer.signMessages([message])).rejects.toThrow('Vault API error: key not found');
|
|
181
|
+
});
|
|
182
|
+
it('should handle network errors', async () => {
|
|
183
|
+
vi.mocked(fetch).mockRejectedValueOnce(new Error('Network failure'));
|
|
184
|
+
const signer = new VaultSigner(mockConfig);
|
|
185
|
+
const message = {
|
|
186
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
187
|
+
signatures: {},
|
|
188
|
+
};
|
|
189
|
+
await expect(signer.signMessages([message])).rejects.toThrow('Vault network request failed');
|
|
190
|
+
});
|
|
191
|
+
it('should handle missing signature in response', async () => {
|
|
192
|
+
const mockResponse = {
|
|
193
|
+
data: {},
|
|
194
|
+
};
|
|
195
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
196
|
+
status: 200,
|
|
197
|
+
}));
|
|
198
|
+
const signer = new VaultSigner(mockConfig);
|
|
199
|
+
const message = {
|
|
200
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
201
|
+
signatures: {},
|
|
202
|
+
};
|
|
203
|
+
await expect(signer.signMessages([message])).rejects.toThrow('Missing signature in Vault response');
|
|
204
|
+
});
|
|
205
|
+
it('should handle signature without vault prefix', async () => {
|
|
206
|
+
const mockSignature = 'a'.repeat(86); // Base64 encoded signature without prefix
|
|
207
|
+
const mockResponse = {
|
|
208
|
+
data: {
|
|
209
|
+
signature: mockSignature,
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
213
|
+
status: 200,
|
|
214
|
+
}));
|
|
215
|
+
const signer = new VaultSigner(mockConfig);
|
|
216
|
+
const message = {
|
|
217
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
218
|
+
signatures: {},
|
|
219
|
+
};
|
|
220
|
+
const [result] = await signer.signMessages([message]);
|
|
221
|
+
expect(result).toHaveProperty(mockConfig.publicKey);
|
|
222
|
+
});
|
|
223
|
+
it('should apply request delay for multiple messages', async () => {
|
|
224
|
+
const mockSignature = 'vault:v1:' + 'a'.repeat(86);
|
|
225
|
+
const mockResponse = {
|
|
226
|
+
data: {
|
|
227
|
+
signature: mockSignature,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
vi.mocked(fetch).mockImplementation(() => Promise.resolve(new Response(JSON.stringify(mockResponse), {
|
|
231
|
+
status: 200,
|
|
232
|
+
})));
|
|
233
|
+
const delaySpy = vi.spyOn(global, 'setTimeout');
|
|
234
|
+
const signer = new VaultSigner({
|
|
235
|
+
...mockConfig,
|
|
236
|
+
requestDelayMs: 100,
|
|
237
|
+
});
|
|
238
|
+
const messages = [
|
|
239
|
+
{ content: new Uint8Array([1, 2, 3, 4]), signatures: {} },
|
|
240
|
+
{ content: new Uint8Array([5, 6, 7, 8]), signatures: {} },
|
|
241
|
+
{ content: new Uint8Array([9, 10, 11, 12]), signatures: {} },
|
|
242
|
+
];
|
|
243
|
+
await signer.signMessages(messages);
|
|
244
|
+
// First message should not have delay, subsequent ones should
|
|
245
|
+
expect(delaySpy).toHaveBeenCalledTimes(2);
|
|
246
|
+
expect(delaySpy).toHaveBeenNthCalledWith(1, expect.any(Function), 100);
|
|
247
|
+
expect(delaySpy).toHaveBeenNthCalledWith(2, expect.any(Function), 200);
|
|
248
|
+
delaySpy.mockRestore();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('signTransactions', () => {
|
|
252
|
+
it('should sign a transaction successfully', async () => {
|
|
253
|
+
const mockSignature = 'vault:v1:' + 'a'.repeat(86);
|
|
254
|
+
const mockResponse = {
|
|
255
|
+
data: {
|
|
256
|
+
signature: mockSignature,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify(mockResponse), {
|
|
260
|
+
status: 200,
|
|
261
|
+
}));
|
|
262
|
+
const signer = new VaultSigner(mockConfig);
|
|
263
|
+
// Create a mock transaction - this is simplified
|
|
264
|
+
const mockTransaction = {
|
|
265
|
+
'"__transactionSize:@solana/kit"': 100,
|
|
266
|
+
lifetimeConstraint: { blockhash: 'test', lastValidBlockHeight: 100n },
|
|
267
|
+
messageBytes: new Uint8Array([1, 2, 3, 4]),
|
|
268
|
+
signatures: {},
|
|
269
|
+
};
|
|
270
|
+
const [result] = await signer.signTransactions([mockTransaction]);
|
|
271
|
+
expect(result).toHaveProperty(mockConfig.publicKey);
|
|
272
|
+
expect(fetch).toHaveBeenCalledWith('https://vault.example.com/v1/transit/sign/test-key', expect.objectContaining({
|
|
273
|
+
headers: {
|
|
274
|
+
'Content-Type': 'application/json',
|
|
275
|
+
'X-Vault-Token': 'test-token',
|
|
276
|
+
},
|
|
277
|
+
method: 'POST',
|
|
278
|
+
}));
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
//# sourceMappingURL=vault-signer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-signer.test.js","sourceRoot":"","sources":["../../src/__tests__/vault-signer.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { VaultSigner } from './vault-signer.js';
|
|
2
|
+
export type { VaultSignerConfig } from './vault-signer.js';
|
|
3
|
+
export type { VaultErrorResponse, VaultKeyReadRequest, VaultKeyReadResponse, VaultPayloadBase64, VaultSignatureBase64, VaultSignRequest, VaultSignResponse, } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EACR,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GACpB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64 encoded signature string from Vault
|
|
3
|
+
*/
|
|
4
|
+
export type VaultSignatureBase64 = string & {
|
|
5
|
+
readonly __brand: unique symbol;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Base64 encoded transaction payload for Vault
|
|
9
|
+
*/
|
|
10
|
+
export type VaultPayloadBase64 = string & {
|
|
11
|
+
readonly __brand: unique symbol;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Request to sign data using Vault transit engine
|
|
15
|
+
*/
|
|
16
|
+
export interface VaultSignRequest {
|
|
17
|
+
/**
|
|
18
|
+
* Hash algorithm to use (optional, defaults to sha2-256)
|
|
19
|
+
* Not typically needed for ED25519 keys as they handle hashing internally
|
|
20
|
+
*/
|
|
21
|
+
hash_algorithm?: 'sha2-256' | 'sha2-384' | 'sha2-512';
|
|
22
|
+
/**
|
|
23
|
+
* The base64 encoded data to sign
|
|
24
|
+
*/
|
|
25
|
+
input: VaultPayloadBase64;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to hash the input before signing (optional, defaults to false)
|
|
28
|
+
* Not typically sent as Vault defaults to false
|
|
29
|
+
*/
|
|
30
|
+
prehashed?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Signature algorithm (optional)
|
|
33
|
+
* Not typically sent as the key type determines the algorithm
|
|
34
|
+
*/
|
|
35
|
+
signature_algorithm?: 'ed25519' | 'rsa-2048' | 'rsa-3072' | 'rsa-4096';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Response from Vault transit sign endpoint
|
|
39
|
+
*/
|
|
40
|
+
export interface VaultSignResponse {
|
|
41
|
+
/**
|
|
42
|
+
* Optional authentication information
|
|
43
|
+
*/
|
|
44
|
+
auth?: unknown;
|
|
45
|
+
data: {
|
|
46
|
+
/**
|
|
47
|
+
* Optional key version used for signing
|
|
48
|
+
*/
|
|
49
|
+
key_version?: number;
|
|
50
|
+
/**
|
|
51
|
+
* The signature in the format "vault:v1:signature_base64"
|
|
52
|
+
*/
|
|
53
|
+
signature: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Optional warnings from Vault
|
|
57
|
+
*/
|
|
58
|
+
warnings?: string[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Request to read key metadata from Vault transit engine
|
|
62
|
+
* No request body needed for key metadata read
|
|
63
|
+
*/
|
|
64
|
+
export type VaultKeyReadRequest = Record<string, never>;
|
|
65
|
+
/**
|
|
66
|
+
* Response from Vault transit key read endpoint
|
|
67
|
+
*/
|
|
68
|
+
export interface VaultKeyReadResponse {
|
|
69
|
+
data: {
|
|
70
|
+
/**
|
|
71
|
+
* Key creation time
|
|
72
|
+
*/
|
|
73
|
+
creation_time: string;
|
|
74
|
+
/**
|
|
75
|
+
* Whether the key is deletable
|
|
76
|
+
*/
|
|
77
|
+
deletion_allowed: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the key can be exported
|
|
80
|
+
*/
|
|
81
|
+
exportable: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Current version of the key
|
|
84
|
+
*/
|
|
85
|
+
latest_version: number;
|
|
86
|
+
/**
|
|
87
|
+
* Minimum version for decryption
|
|
88
|
+
*/
|
|
89
|
+
min_decryption_version?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Minimum version for encryption
|
|
92
|
+
*/
|
|
93
|
+
min_encryption_version?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Whether the key can be used for encryption
|
|
96
|
+
*/
|
|
97
|
+
supports_encryption: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Whether the key can be used for signing
|
|
100
|
+
*/
|
|
101
|
+
supports_signing: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Key type (e.g., "ed25519", "rsa-2048", etc.)
|
|
104
|
+
*/
|
|
105
|
+
type: string;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Vault error response format
|
|
110
|
+
*/
|
|
111
|
+
export interface VaultErrorResponse {
|
|
112
|
+
errors: string[];
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAEtD;;OAEG;IACH,KAAK,EAAE,kBAAkB,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;CAC1E;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,IAAI,EAAE;QACF;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB;;WAEG;QACH,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE;QACF;;WAEG;QACH,aAAa,EAAE,MAAM,CAAC;QAEtB;;WAEG;QACH,gBAAgB,EAAE,OAAO,CAAC;QAE1B;;WAEG;QACH,UAAU,EAAE,OAAO,CAAC;QAEpB;;WAEG;QACH,cAAc,EAAE,MAAM,CAAC;QAEvB;;WAEG;QACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAEhC;;WAEG;QACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAEhC;;WAEG;QACH,mBAAmB,EAAE,OAAO,CAAC;QAE7B;;WAEG;QACH,gBAAgB,EAAE,OAAO,CAAC;QAE1B;;WAEG;QACH,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|