@solana/keychain-gcp-kms 1.3.0 → 1.4.0
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/dist/gcp-kms-signer.d.ts
CHANGED
|
@@ -34,16 +34,8 @@ export declare class GcpKmsSigner<TAddress extends string = string> implements S
|
|
|
34
34
|
constructor(config: GcpKmsSignerConfig);
|
|
35
35
|
private normalizeKeyName;
|
|
36
36
|
private buildResourceUrl;
|
|
37
|
-
private
|
|
37
|
+
private buildAuthorizedHeaders;
|
|
38
38
|
private request;
|
|
39
|
-
/**
|
|
40
|
-
* Validate request delay ms
|
|
41
|
-
*/
|
|
42
|
-
private validateRequestDelayMs;
|
|
43
|
-
/**
|
|
44
|
-
* Add delay between concurrent requests
|
|
45
|
-
*/
|
|
46
|
-
private delay;
|
|
47
39
|
/**
|
|
48
40
|
* Sign message bytes using GCP KMS EdDSA signing
|
|
49
41
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcp-kms-signer.d.ts","sourceRoot":"","sources":["../src/gcp-kms-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,mBAAmB,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"gcp-kms-signer.d.ts","sourceRoot":"","sources":["../src/gcp-kms-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAOH,YAAY,EAGf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGxG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAmBrD,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAC/D,MAAM,EAAE,kBAAkB,GAC3B,YAAY,CAAC,QAAQ,CAAC,CAExB;AAED;;;;;;;;;;;;;;;;;GAiBG;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,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAoB;IACxD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,sDAAsD;IACtD,MAAM,CAAC,MAAM,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAAC,QAAQ,CAAC;IAInG,+GAA+G;gBACnG,MAAM,EAAE,kBAAkB;IA8BtC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;YAOV,sBAAsB;YAetB,OAAO;IASrB;;OAEG;YACW,SAAS;IAoCvB;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAuBjG;;OAEG;IACG,gBAAgB,CAClB,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,0BAA0B,GAAG,uBAAuB,CAAC,EAAE,GAC9F,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAqB1C;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAgBxC"}
|
package/dist/gcp-kms-signer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertIsAddress } from '@solana/addresses';
|
|
2
|
-
import { assertSignatureValid, createSignatureDictionary, ED25519_SIGNATURE_LENGTH,
|
|
2
|
+
import { assertSignatureValid, createSignatureDictionary, ED25519_SIGNATURE_LENGTH, fetchSignerJson, signBatchStaggered, SignerErrorCode, throwSignerError, validateRequestDelayMs, } from '@solana/keychain-core';
|
|
3
3
|
import { GoogleAuth } from 'google-auth-library';
|
|
4
4
|
/**
|
|
5
5
|
* Create a Google Cloud KMS-backed signer.
|
|
@@ -60,7 +60,7 @@ export class GcpKmsSigner {
|
|
|
60
60
|
this.keyName = this.normalizeKeyName(config.keyName);
|
|
61
61
|
this.keyNamePathSegments = this.keyName.split('/');
|
|
62
62
|
this.requestDelayMs = config.requestDelayMs || 0;
|
|
63
|
-
|
|
63
|
+
validateRequestDelayMs(this.requestDelayMs);
|
|
64
64
|
this.auth = new GoogleAuth({ scopes: [CLOUD_KMS_SCOPE] });
|
|
65
65
|
}
|
|
66
66
|
normalizeKeyName(keyName) {
|
|
@@ -83,7 +83,7 @@ export class GcpKmsSigner {
|
|
|
83
83
|
url.pathname = `/${[...basePathSegments, ...this.keyNamePathSegments].join('/')}${suffix}`;
|
|
84
84
|
return url.toString();
|
|
85
85
|
}
|
|
86
|
-
async
|
|
86
|
+
async buildAuthorizedHeaders(url, init) {
|
|
87
87
|
const authHeaders = await this.auth.getRequestHeaders(url);
|
|
88
88
|
const headers = new Headers(init.headers);
|
|
89
89
|
authHeaders.forEach((value, key) => {
|
|
@@ -92,60 +92,15 @@ export class GcpKmsSigner {
|
|
|
92
92
|
if (init.body && !headers.has('content-type')) {
|
|
93
93
|
headers.set('content-type', 'application/json');
|
|
94
94
|
}
|
|
95
|
-
return
|
|
95
|
+
return headers;
|
|
96
96
|
}
|
|
97
97
|
async request(url, init) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
cause: error,
|
|
105
|
-
message: 'GCP KMS network request failed',
|
|
106
|
-
url,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
if (!response.ok) {
|
|
110
|
-
const errorText = await response.text().catch(() => 'Failed to read error response');
|
|
111
|
-
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
112
|
-
message: `GCP KMS API error: ${response.status}`,
|
|
113
|
-
response: sanitizeRemoteErrorResponse(errorText),
|
|
114
|
-
status: response.status,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
let payload;
|
|
118
|
-
try {
|
|
119
|
-
payload = (await response.json());
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
throwSignerError(SignerErrorCode.PARSING_ERROR, {
|
|
123
|
-
cause: error,
|
|
124
|
-
message: 'Failed to parse GCP KMS response',
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
return payload;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Validate request delay ms
|
|
131
|
-
*/
|
|
132
|
-
validateRequestDelayMs(requestDelayMs) {
|
|
133
|
-
if (requestDelayMs < 0) {
|
|
134
|
-
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
135
|
-
message: 'requestDelayMs must not be negative',
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
if (requestDelayMs > 3000) {
|
|
139
|
-
console.warn('requestDelayMs is greater than 3000ms, this may result in blockhash expiration errors for signing messages/transactions');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Add delay between concurrent requests
|
|
144
|
-
*/
|
|
145
|
-
async delay(index) {
|
|
146
|
-
if (this.requestDelayMs > 0 && index > 0) {
|
|
147
|
-
await new Promise(resolve => setTimeout(resolve, index * this.requestDelayMs));
|
|
148
|
-
}
|
|
98
|
+
const headers = await this.buildAuthorizedHeaders(url, init);
|
|
99
|
+
return await fetchSignerJson({
|
|
100
|
+
init: { ...init, headers },
|
|
101
|
+
providerName: 'GCP KMS',
|
|
102
|
+
url,
|
|
103
|
+
});
|
|
149
104
|
}
|
|
150
105
|
/**
|
|
151
106
|
* Sign message bytes using GCP KMS EdDSA signing
|
|
@@ -187,8 +142,7 @@ export class GcpKmsSigner {
|
|
|
187
142
|
* Sign multiple messages using GCP KMS
|
|
188
143
|
*/
|
|
189
144
|
async signMessages(messages) {
|
|
190
|
-
return await
|
|
191
|
-
await this.delay(index);
|
|
145
|
+
return await signBatchStaggered(messages, async (message) => {
|
|
192
146
|
const messageBytes = message.content instanceof Uint8Array
|
|
193
147
|
? message.content
|
|
194
148
|
: new Uint8Array(Array.from(message.content));
|
|
@@ -202,14 +156,13 @@ export class GcpKmsSigner {
|
|
|
202
156
|
signature: signatureBytes,
|
|
203
157
|
signerAddress: this.address,
|
|
204
158
|
});
|
|
205
|
-
})
|
|
159
|
+
}, this.requestDelayMs);
|
|
206
160
|
}
|
|
207
161
|
/**
|
|
208
162
|
* Sign multiple transactions using GCP KMS
|
|
209
163
|
*/
|
|
210
164
|
async signTransactions(transactions) {
|
|
211
|
-
return await
|
|
212
|
-
await this.delay(index);
|
|
165
|
+
return await signBatchStaggered(transactions, async (transaction) => {
|
|
213
166
|
// Sign the transaction message bytes
|
|
214
167
|
const txMessageBytes = new Uint8Array(transaction.messageBytes);
|
|
215
168
|
const signatureBytes = await this.signBytes(txMessageBytes);
|
|
@@ -222,7 +175,7 @@ export class GcpKmsSigner {
|
|
|
222
175
|
signature: signatureBytes,
|
|
223
176
|
signerAddress: this.address,
|
|
224
177
|
});
|
|
225
|
-
})
|
|
178
|
+
}, this.requestDelayMs);
|
|
226
179
|
}
|
|
227
180
|
/**
|
|
228
181
|
* Check if GCP KMS is available and the key is accessible
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcp-kms-signer.js","sourceRoot":"","sources":["../src/gcp-kms-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACH,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,
|
|
1
|
+
{"version":3,"file":"gcp-kms-signer.js","sourceRoot":"","sources":["../src/gcp-kms-signer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/keychain-gcp-kms",
|
|
3
3
|
"author": "Solana Foundation",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "Google Cloud KMS-based signer for Solana transactions using EdDSA (Ed25519)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "https://github.com/solana-foundation/solana-keychain",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"src"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"google-auth-library": "^10.
|
|
33
|
-
"@solana/keychain-core": "1.
|
|
32
|
+
"google-auth-library": "^10.7.0",
|
|
33
|
+
"@solana/keychain-core": "1.4.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@solana/addresses": ">=6.0.1",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@solana-program/memo": "^0.11.0",
|
|
47
47
|
"@solana/kit": "^6.9.0",
|
|
48
48
|
"dotenv": "^17.4.2",
|
|
49
|
-
"@solana/keychain-test-utils": "1.
|
|
49
|
+
"@solana/keychain-test-utils": "1.4.0"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
package/src/gcp-kms-signer.ts
CHANGED
|
@@ -3,10 +3,12 @@ import {
|
|
|
3
3
|
assertSignatureValid,
|
|
4
4
|
createSignatureDictionary,
|
|
5
5
|
ED25519_SIGNATURE_LENGTH,
|
|
6
|
-
|
|
6
|
+
fetchSignerJson,
|
|
7
|
+
signBatchStaggered,
|
|
7
8
|
SignerErrorCode,
|
|
8
9
|
SolanaSigner,
|
|
9
10
|
throwSignerError,
|
|
11
|
+
validateRequestDelayMs,
|
|
10
12
|
} from '@solana/keychain-core';
|
|
11
13
|
import { SignatureBytes } from '@solana/keys';
|
|
12
14
|
import { SignableMessage, SignatureDictionary } from '@solana/signers';
|
|
@@ -95,7 +97,7 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
95
97
|
this.keyName = this.normalizeKeyName(config.keyName);
|
|
96
98
|
this.keyNamePathSegments = this.keyName.split('/');
|
|
97
99
|
this.requestDelayMs = config.requestDelayMs || 0;
|
|
98
|
-
|
|
100
|
+
validateRequestDelayMs(this.requestDelayMs);
|
|
99
101
|
this.auth = new GoogleAuth({ scopes: [CLOUD_KMS_SCOPE] });
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -124,7 +126,7 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
124
126
|
return url.toString();
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
private async
|
|
129
|
+
private async buildAuthorizedHeaders(url: string, init: RequestInit): Promise<Headers> {
|
|
128
130
|
const authHeaders = await this.auth.getRequestHeaders(url);
|
|
129
131
|
const headers = new Headers(init.headers);
|
|
130
132
|
|
|
@@ -136,66 +138,16 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
136
138
|
headers.set('content-type', 'application/json');
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
return
|
|
141
|
+
return headers;
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
private async request<TResponse>(url: string, init: RequestInit): Promise<TResponse> {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
message: 'GCP KMS network request failed',
|
|
150
|
-
url,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!response.ok) {
|
|
155
|
-
const errorText = await response.text().catch(() => 'Failed to read error response');
|
|
156
|
-
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
157
|
-
message: `GCP KMS API error: ${response.status}`,
|
|
158
|
-
response: sanitizeRemoteErrorResponse(errorText),
|
|
159
|
-
status: response.status,
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
let payload: TResponse;
|
|
164
|
-
try {
|
|
165
|
-
payload = (await response.json()) as TResponse;
|
|
166
|
-
} catch (error) {
|
|
167
|
-
throwSignerError(SignerErrorCode.PARSING_ERROR, {
|
|
168
|
-
cause: error,
|
|
169
|
-
message: 'Failed to parse GCP KMS response',
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return payload;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Validate request delay ms
|
|
178
|
-
*/
|
|
179
|
-
private validateRequestDelayMs(requestDelayMs: number): void {
|
|
180
|
-
if (requestDelayMs < 0) {
|
|
181
|
-
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
182
|
-
message: 'requestDelayMs must not be negative',
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
if (requestDelayMs > 3000) {
|
|
186
|
-
console.warn(
|
|
187
|
-
'requestDelayMs is greater than 3000ms, this may result in blockhash expiration errors for signing messages/transactions',
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Add delay between concurrent requests
|
|
194
|
-
*/
|
|
195
|
-
private async delay(index: number): Promise<void> {
|
|
196
|
-
if (this.requestDelayMs > 0 && index > 0) {
|
|
197
|
-
await new Promise(resolve => setTimeout(resolve, index * this.requestDelayMs));
|
|
198
|
-
}
|
|
145
|
+
const headers = await this.buildAuthorizedHeaders(url, init);
|
|
146
|
+
return await fetchSignerJson<TResponse>({
|
|
147
|
+
init: { ...init, headers },
|
|
148
|
+
providerName: 'GCP KMS',
|
|
149
|
+
url,
|
|
150
|
+
});
|
|
199
151
|
}
|
|
200
152
|
|
|
201
153
|
/**
|
|
@@ -241,9 +193,9 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
241
193
|
* Sign multiple messages using GCP KMS
|
|
242
194
|
*/
|
|
243
195
|
async signMessages(messages: readonly SignableMessage[]): Promise<readonly SignatureDictionary[]> {
|
|
244
|
-
return await
|
|
245
|
-
messages
|
|
246
|
-
|
|
196
|
+
return await signBatchStaggered(
|
|
197
|
+
messages,
|
|
198
|
+
async message => {
|
|
247
199
|
const messageBytes =
|
|
248
200
|
message.content instanceof Uint8Array
|
|
249
201
|
? message.content
|
|
@@ -258,7 +210,8 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
258
210
|
signature: signatureBytes,
|
|
259
211
|
signerAddress: this.address,
|
|
260
212
|
});
|
|
261
|
-
}
|
|
213
|
+
},
|
|
214
|
+
this.requestDelayMs,
|
|
262
215
|
);
|
|
263
216
|
}
|
|
264
217
|
|
|
@@ -268,9 +221,9 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
268
221
|
async signTransactions(
|
|
269
222
|
transactions: readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[],
|
|
270
223
|
): Promise<readonly SignatureDictionary[]> {
|
|
271
|
-
return await
|
|
272
|
-
transactions
|
|
273
|
-
|
|
224
|
+
return await signBatchStaggered(
|
|
225
|
+
transactions,
|
|
226
|
+
async transaction => {
|
|
274
227
|
// Sign the transaction message bytes
|
|
275
228
|
const txMessageBytes = new Uint8Array(transaction.messageBytes);
|
|
276
229
|
const signatureBytes = await this.signBytes(txMessageBytes);
|
|
@@ -283,7 +236,8 @@ export class GcpKmsSigner<TAddress extends string = string> implements SolanaSig
|
|
|
283
236
|
signature: signatureBytes,
|
|
284
237
|
signerAddress: this.address,
|
|
285
238
|
});
|
|
286
|
-
}
|
|
239
|
+
},
|
|
240
|
+
this.requestDelayMs,
|
|
287
241
|
);
|
|
288
242
|
}
|
|
289
243
|
|