@solana/keychain-crossmint 0.0.0 → 0.6.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/README.md +40 -0
- package/dist/__tests__/crossmint-signer.integration.test.d.ts +2 -0
- package/dist/__tests__/crossmint-signer.integration.test.d.ts.map +1 -0
- package/dist/__tests__/crossmint-signer.integration.test.js +44 -0
- package/dist/__tests__/crossmint-signer.integration.test.js.map +1 -0
- package/dist/__tests__/crossmint-signer.test.d.ts +2 -0
- package/dist/__tests__/crossmint-signer.test.d.ts.map +1 -0
- package/dist/__tests__/crossmint-signer.test.js +275 -0
- package/dist/__tests__/crossmint-signer.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +27 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/crossmint-signer.d.ts +4 -0
- package/dist/crossmint-signer.d.ts.map +1 -0
- package/dist/crossmint-signer.js +448 -0
- package/dist/crossmint-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 +50 -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 +53 -8
- package/src/__tests__/crossmint-signer.integration.test.ts +63 -0
- package/src/__tests__/crossmint-signer.test.ts +373 -0
- package/src/__tests__/setup.ts +32 -0
- package/src/crossmint-signer.ts +564 -0
- package/src/index.ts +2 -0
- package/src/types.ts +56 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import { createPrivateKey, createPublicKey, hkdfSync, sign as cryptoSign } from 'node:crypto';
|
|
2
|
+
import { assertIsAddress } from '@solana/addresses';
|
|
3
|
+
import { getBase16Encoder, getBase58Decoder, getBase58Encoder, getBase64Decoder, getBase64Encoder, } from '@solana/codecs-strings';
|
|
4
|
+
import { createSignatureDictionary, createSignerError, extractSignatureFromWireTransaction, SignerErrorCode, throwSignerError, } from '@solana/keychain-core';
|
|
5
|
+
import { getBase64EncodedWireTransaction, } from '@solana/transactions';
|
|
6
|
+
export async function createCrossmintSigner(config) {
|
|
7
|
+
return await CrossmintSigner.create(config);
|
|
8
|
+
}
|
|
9
|
+
const API_VERSION = '2025-06-09';
|
|
10
|
+
const DEFAULT_API_BASE_URL = 'https://www.crossmint.com/api';
|
|
11
|
+
const DEFAULT_POLL_INTERVAL_MS = 1000;
|
|
12
|
+
const DEFAULT_MAX_POLL_ATTEMPTS = 60;
|
|
13
|
+
let base16Encoder;
|
|
14
|
+
let base58Decoder;
|
|
15
|
+
let base58Encoder;
|
|
16
|
+
let base64Decoder;
|
|
17
|
+
let base64Encoder;
|
|
18
|
+
class CrossmintSigner {
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.address = config.address;
|
|
21
|
+
this.apiKey = config.apiKey;
|
|
22
|
+
this.walletLocator = config.walletLocator;
|
|
23
|
+
this.apiBaseUrl = config.apiBaseUrl;
|
|
24
|
+
this.pollIntervalMs = config.pollIntervalMs;
|
|
25
|
+
this.maxPollAttempts = config.maxPollAttempts;
|
|
26
|
+
this.requestDelayMs = config.requestDelayMs;
|
|
27
|
+
this.signerSeed = config.signerSeed;
|
|
28
|
+
this.signer = config.signer;
|
|
29
|
+
}
|
|
30
|
+
static async create(config) {
|
|
31
|
+
if (!config.apiKey) {
|
|
32
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
33
|
+
message: 'Missing required apiKey field',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (!config.walletLocator) {
|
|
37
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
38
|
+
message: 'Missing required walletLocator field',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const apiBaseUrl = normalizeBaseUrl(config.apiBaseUrl ?? DEFAULT_API_BASE_URL);
|
|
42
|
+
let parsedUrl;
|
|
43
|
+
try {
|
|
44
|
+
parsedUrl = new URL(apiBaseUrl);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
48
|
+
cause: error,
|
|
49
|
+
message: `Invalid apiBaseUrl: ${apiBaseUrl}`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (parsedUrl.protocol !== 'https:') {
|
|
53
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
54
|
+
message: 'apiBaseUrl must use HTTPS',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
58
|
+
if (pollIntervalMs <= 0) {
|
|
59
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
60
|
+
message: 'pollIntervalMs must be greater than 0',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const maxPollAttempts = config.maxPollAttempts ?? DEFAULT_MAX_POLL_ATTEMPTS;
|
|
64
|
+
if (maxPollAttempts <= 0) {
|
|
65
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
66
|
+
message: 'maxPollAttempts must be greater than 0',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const requestDelayMs = config.requestDelayMs ?? 0;
|
|
70
|
+
if (requestDelayMs < 0) {
|
|
71
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
72
|
+
message: 'requestDelayMs must not be negative',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (requestDelayMs > 3000) {
|
|
76
|
+
console.warn('requestDelayMs is greater than 3000ms, this may result in blockhash expiration errors for signing messages/transactions');
|
|
77
|
+
}
|
|
78
|
+
let signerSeed;
|
|
79
|
+
let signer = config.signer;
|
|
80
|
+
if (config.signerSecret) {
|
|
81
|
+
signerSeed = deriveSignerSeed(config.signerSecret, config.apiKey);
|
|
82
|
+
if (!signer) {
|
|
83
|
+
base58Decoder || (base58Decoder = getBase58Decoder());
|
|
84
|
+
signer = `server:${base58Decoder.decode(ed25519PublicKeyFromSeed(signerSeed))}`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const wallet = await fetchWallet(apiBaseUrl, config.apiKey, config.walletLocator);
|
|
88
|
+
if (wallet.chainType.toLowerCase() !== 'solana') {
|
|
89
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
90
|
+
message: `Expected Solana wallet, got chainType=${wallet.chainType}`,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (wallet.type.toLowerCase() !== 'smart' && wallet.type.toLowerCase() !== 'mpc') {
|
|
94
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
95
|
+
message: `Unsupported Crossmint wallet type: ${wallet.type}`,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
let address;
|
|
99
|
+
try {
|
|
100
|
+
assertIsAddress(wallet.address);
|
|
101
|
+
address = wallet.address;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
throwSignerError(SignerErrorCode.INVALID_PUBLIC_KEY, {
|
|
105
|
+
cause: error,
|
|
106
|
+
message: 'Invalid Solana address from Crossmint wallet response',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return new CrossmintSigner({
|
|
110
|
+
address,
|
|
111
|
+
apiBaseUrl,
|
|
112
|
+
apiKey: config.apiKey,
|
|
113
|
+
maxPollAttempts,
|
|
114
|
+
pollIntervalMs,
|
|
115
|
+
requestDelayMs,
|
|
116
|
+
signer,
|
|
117
|
+
signerSeed,
|
|
118
|
+
walletLocator: config.walletLocator,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async signMessages(_messages) {
|
|
122
|
+
return await Promise.reject(createSignerError(SignerErrorCode.SIGNING_FAILED, {
|
|
123
|
+
message: 'Crossmint signMessages is not supported for Solana wallets in this signer',
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
async signTransactions(transactions) {
|
|
127
|
+
return await Promise.all(transactions.map(async (transaction, index) => {
|
|
128
|
+
if (this.requestDelayMs > 0 && index > 0) {
|
|
129
|
+
await new Promise(resolve => setTimeout(resolve, index * this.requestDelayMs));
|
|
130
|
+
}
|
|
131
|
+
const signature = await this.signTransactionManaged(transaction);
|
|
132
|
+
return createSignatureDictionary({
|
|
133
|
+
signature,
|
|
134
|
+
signerAddress: this.address,
|
|
135
|
+
});
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
async isAvailable() {
|
|
139
|
+
try {
|
|
140
|
+
await fetchWallet(this.apiBaseUrl, this.apiKey, this.walletLocator);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async signTransactionManaged(transaction) {
|
|
148
|
+
let response = await this.createTransaction(transaction);
|
|
149
|
+
for (let attempt = 0; attempt < this.maxPollAttempts; attempt++) {
|
|
150
|
+
if (response.status === 'awaiting-approval' && this.signerSeed && this.signer) {
|
|
151
|
+
response = await this.submitApproval(response);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const terminalSignature = this.resolveTerminalStatus(response);
|
|
155
|
+
if (terminalSignature) {
|
|
156
|
+
return terminalSignature;
|
|
157
|
+
}
|
|
158
|
+
await new Promise(resolve => setTimeout(resolve, this.pollIntervalMs));
|
|
159
|
+
response = await this.getTransaction(response.id);
|
|
160
|
+
}
|
|
161
|
+
const terminalSignature = this.resolveTerminalStatus(response);
|
|
162
|
+
if (terminalSignature) {
|
|
163
|
+
return terminalSignature;
|
|
164
|
+
}
|
|
165
|
+
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
166
|
+
message: `Crossmint transaction polling timed out after ${this.maxPollAttempts} attempts`,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
resolveTerminalStatus(response) {
|
|
170
|
+
const status = response.status;
|
|
171
|
+
switch (status) {
|
|
172
|
+
case 'success':
|
|
173
|
+
return this.extractSignature(response);
|
|
174
|
+
case 'failed':
|
|
175
|
+
return throwSignerError(SignerErrorCode.SIGNING_FAILED, {
|
|
176
|
+
message: `Crossmint transaction failed: ${stringifyError(response.error)}`,
|
|
177
|
+
});
|
|
178
|
+
case 'awaiting-approval':
|
|
179
|
+
return throwSignerError(SignerErrorCode.SIGNING_FAILED, {
|
|
180
|
+
message: 'Crossmint transaction is awaiting approval; additional signer approvals are required',
|
|
181
|
+
});
|
|
182
|
+
case 'pending':
|
|
183
|
+
default:
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async submitApproval(response) {
|
|
188
|
+
const message = response.approvals?.pending?.[0]?.message;
|
|
189
|
+
if (!message) {
|
|
190
|
+
throwSignerError(SignerErrorCode.SIGNING_FAILED, {
|
|
191
|
+
message: 'Crossmint transaction awaiting approval but no pending message found',
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
base58Encoder || (base58Encoder = getBase58Encoder());
|
|
195
|
+
const messageBytes = new Uint8Array(base58Encoder.encode(message));
|
|
196
|
+
const signatureBytes = ed25519Sign(this.signerSeed, messageBytes);
|
|
197
|
+
base58Decoder || (base58Decoder = getBase58Decoder());
|
|
198
|
+
const signatureB58 = base58Decoder.decode(signatureBytes);
|
|
199
|
+
const path = `/${API_VERSION}/wallets/${encodeURIComponent(this.walletLocator)}/transactions/${encodeURIComponent(response.id)}/approvals`;
|
|
200
|
+
const result = await this.request(path, 'POST', {
|
|
201
|
+
approvals: [{ signature: signatureB58, signer: this.signer }],
|
|
202
|
+
});
|
|
203
|
+
return parseTransactionResponse(result, 'submit approval');
|
|
204
|
+
}
|
|
205
|
+
async createTransaction(transaction) {
|
|
206
|
+
const wireTransaction = getBase64EncodedWireTransaction(transaction);
|
|
207
|
+
base64Encoder || (base64Encoder = getBase64Encoder());
|
|
208
|
+
const transactionBytes = base64Encoder.encode(wireTransaction);
|
|
209
|
+
base58Decoder || (base58Decoder = getBase58Decoder());
|
|
210
|
+
const transactionBase58 = base58Decoder.decode(transactionBytes);
|
|
211
|
+
const body = {
|
|
212
|
+
params: {
|
|
213
|
+
transaction: transactionBase58,
|
|
214
|
+
...(this.signer ? { signer: this.signer } : {}),
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
const path = `/${API_VERSION}/wallets/${encodeURIComponent(this.walletLocator)}/transactions`;
|
|
218
|
+
const response = await this.request(path, 'POST', body);
|
|
219
|
+
return parseTransactionResponse(response, 'create transaction');
|
|
220
|
+
}
|
|
221
|
+
async getTransaction(transactionId) {
|
|
222
|
+
const path = `/${API_VERSION}/wallets/${encodeURIComponent(this.walletLocator)}/transactions/${encodeURIComponent(transactionId)}`;
|
|
223
|
+
const response = await this.request(path, 'GET');
|
|
224
|
+
return parseTransactionResponse(response, 'get transaction');
|
|
225
|
+
}
|
|
226
|
+
async request(path, method, body) {
|
|
227
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
228
|
+
const headers = {
|
|
229
|
+
'X-API-KEY': this.apiKey,
|
|
230
|
+
};
|
|
231
|
+
if (method === 'POST' && body != null) {
|
|
232
|
+
headers['Content-Type'] = 'application/json';
|
|
233
|
+
}
|
|
234
|
+
let response;
|
|
235
|
+
try {
|
|
236
|
+
response = await fetch(url, {
|
|
237
|
+
body: body != null ? JSON.stringify(body) : undefined,
|
|
238
|
+
headers,
|
|
239
|
+
method,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
throwSignerError(SignerErrorCode.HTTP_ERROR, {
|
|
244
|
+
cause: error,
|
|
245
|
+
message: 'Crossmint network request failed',
|
|
246
|
+
url,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
let payload;
|
|
250
|
+
try {
|
|
251
|
+
payload = await response.json();
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
throwSignerError(SignerErrorCode.PARSING_ERROR, {
|
|
255
|
+
cause: error,
|
|
256
|
+
message: 'Failed to parse Crossmint response',
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
261
|
+
message: extractApiErrorMessage(payload, `Crossmint API error: ${response.status}`),
|
|
262
|
+
status: response.status,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return payload;
|
|
266
|
+
}
|
|
267
|
+
extractSignature(response) {
|
|
268
|
+
const fromSerialized = this.extractSignatureFromSerializedTransaction(response.onChain?.transaction);
|
|
269
|
+
if (fromSerialized) {
|
|
270
|
+
return fromSerialized;
|
|
271
|
+
}
|
|
272
|
+
const fromTxId = decodeSignatureString(response.onChain?.txId);
|
|
273
|
+
if (fromTxId) {
|
|
274
|
+
return fromTxId;
|
|
275
|
+
}
|
|
276
|
+
const submitted = response.approvals?.submitted ?? [];
|
|
277
|
+
for (const approval of submitted) {
|
|
278
|
+
const signature = decodeSignatureString(approval.signature);
|
|
279
|
+
if (signature) {
|
|
280
|
+
return signature;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
throwSignerError(SignerErrorCode.SIGNING_FAILED, {
|
|
284
|
+
message: 'Unable to extract signature from Crossmint transaction response',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
extractSignatureFromSerializedTransaction(serializedTransaction) {
|
|
288
|
+
if (!serializedTransaction)
|
|
289
|
+
return undefined;
|
|
290
|
+
try {
|
|
291
|
+
base58Encoder || (base58Encoder = getBase58Encoder());
|
|
292
|
+
const txBytes = base58Encoder.encode(serializedTransaction);
|
|
293
|
+
base64Decoder || (base64Decoder = getBase64Decoder());
|
|
294
|
+
const base64WireTransaction = base64Decoder.decode(txBytes);
|
|
295
|
+
const signatureDict = extractSignatureFromWireTransaction({
|
|
296
|
+
base64WireTransaction,
|
|
297
|
+
signerAddress: this.address,
|
|
298
|
+
});
|
|
299
|
+
return signatureDict[this.address];
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function normalizeBaseUrl(baseUrl) {
|
|
307
|
+
return baseUrl.replace(/\/+$/, '');
|
|
308
|
+
}
|
|
309
|
+
async function fetchWallet(apiBaseUrl, apiKey, walletLocator) {
|
|
310
|
+
const url = `${apiBaseUrl}/${API_VERSION}/wallets/${encodeURIComponent(walletLocator)}`;
|
|
311
|
+
let response;
|
|
312
|
+
try {
|
|
313
|
+
response = await fetch(url, {
|
|
314
|
+
headers: {
|
|
315
|
+
'X-API-KEY': apiKey,
|
|
316
|
+
},
|
|
317
|
+
method: 'GET',
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
throwSignerError(SignerErrorCode.HTTP_ERROR, {
|
|
322
|
+
cause: error,
|
|
323
|
+
message: 'Crossmint network request failed',
|
|
324
|
+
url,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
let payload;
|
|
328
|
+
try {
|
|
329
|
+
payload = await response.json();
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
throwSignerError(SignerErrorCode.PARSING_ERROR, {
|
|
333
|
+
cause: error,
|
|
334
|
+
message: 'Failed to parse Crossmint wallet response',
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (!response.ok) {
|
|
338
|
+
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
339
|
+
message: extractApiErrorMessage(payload, `Crossmint API error: ${response.status}`),
|
|
340
|
+
status: response.status,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
const wallet = payload;
|
|
344
|
+
if (!wallet.address || !wallet.chainType || !wallet.type) {
|
|
345
|
+
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
346
|
+
message: extractApiErrorMessage(payload, 'Crossmint wallet response missing required fields (address, chainType, type)'),
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
return wallet;
|
|
350
|
+
}
|
|
351
|
+
function parseTransactionResponse(payload, context) {
|
|
352
|
+
const transaction = payload;
|
|
353
|
+
if (!transaction.id || !transaction.status) {
|
|
354
|
+
throwSignerError(SignerErrorCode.REMOTE_API_ERROR, {
|
|
355
|
+
message: extractApiErrorMessage(payload, `Failed to ${context}: missing transaction id/status`),
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
return transaction;
|
|
359
|
+
}
|
|
360
|
+
function extractApiErrorMessage(payload, fallback) {
|
|
361
|
+
if (payload && typeof payload === 'object') {
|
|
362
|
+
const obj = payload;
|
|
363
|
+
if (typeof obj.message === 'string')
|
|
364
|
+
return obj.message;
|
|
365
|
+
if (typeof obj.error === 'string')
|
|
366
|
+
return obj.error;
|
|
367
|
+
if (obj.error && typeof obj.error === 'object') {
|
|
368
|
+
const errorObj = obj.error;
|
|
369
|
+
if (typeof errorObj.message === 'string')
|
|
370
|
+
return errorObj.message;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return fallback;
|
|
374
|
+
}
|
|
375
|
+
function decodeSignatureString(value) {
|
|
376
|
+
if (!value)
|
|
377
|
+
return undefined;
|
|
378
|
+
base58Encoder || (base58Encoder = getBase58Encoder());
|
|
379
|
+
try {
|
|
380
|
+
const bytes = base58Encoder.encode(value);
|
|
381
|
+
return bytes.length === 64 ? bytes : undefined;
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
return undefined;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
388
|
+
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20,
|
|
389
|
+
]);
|
|
390
|
+
function deriveSignerSeed(secret, apiKey) {
|
|
391
|
+
const rawSecret = secret.startsWith('xmsk1_') ? secret.slice(6) : secret;
|
|
392
|
+
if (rawSecret.length !== 64) {
|
|
393
|
+
throwSignerError(SignerErrorCode.CONFIG_ERROR, {
|
|
394
|
+
message: `signerSecret must be a 64-char hex string, got ${rawSecret.length} chars`,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
base16Encoder || (base16Encoder = getBase16Encoder());
|
|
398
|
+
const ikm = Buffer.from(base16Encoder.encode(rawSecret));
|
|
399
|
+
// Parse API key: {ck|sk}_{environment}_{base58data}
|
|
400
|
+
// base58-decoded data is UTF-8: "projectId:nacl_signature"
|
|
401
|
+
const parts = apiKey.split('_');
|
|
402
|
+
const environment = parts[1];
|
|
403
|
+
const base58Data = parts.slice(2).join('_');
|
|
404
|
+
base58Encoder || (base58Encoder = getBase58Encoder());
|
|
405
|
+
const decoded = base58Encoder.encode(base58Data);
|
|
406
|
+
const projectId = new TextDecoder().decode(decoded).split(':')[0];
|
|
407
|
+
const info = `${projectId}:${environment}:solana-ed25519`;
|
|
408
|
+
return new Uint8Array(hkdfSync('sha256', ikm, 'crossmint', info, 32));
|
|
409
|
+
}
|
|
410
|
+
function buildPkcs8Der(seed) {
|
|
411
|
+
return Buffer.concat([PKCS8_ED25519_PREFIX, seed]);
|
|
412
|
+
}
|
|
413
|
+
function ed25519PublicKeyFromSeed(seed) {
|
|
414
|
+
const privateKey = createPrivateKey({
|
|
415
|
+
format: 'der',
|
|
416
|
+
key: buildPkcs8Der(seed),
|
|
417
|
+
type: 'pkcs8',
|
|
418
|
+
});
|
|
419
|
+
const spki = createPublicKey(privateKey).export({ format: 'der', type: 'spki' });
|
|
420
|
+
return new Uint8Array(spki.slice(-32));
|
|
421
|
+
}
|
|
422
|
+
function ed25519Sign(seed, message) {
|
|
423
|
+
const privateKey = createPrivateKey({
|
|
424
|
+
format: 'der',
|
|
425
|
+
key: buildPkcs8Der(seed),
|
|
426
|
+
type: 'pkcs8',
|
|
427
|
+
});
|
|
428
|
+
return new Uint8Array(cryptoSign(null, Buffer.from(message), privateKey));
|
|
429
|
+
}
|
|
430
|
+
function stringifyError(error) {
|
|
431
|
+
if (typeof error === 'string')
|
|
432
|
+
return error;
|
|
433
|
+
if (typeof error === 'number' || typeof error === 'boolean' || typeof error === 'bigint') {
|
|
434
|
+
return String(error);
|
|
435
|
+
}
|
|
436
|
+
if (error instanceof Error) {
|
|
437
|
+
return error.message;
|
|
438
|
+
}
|
|
439
|
+
if (error == null)
|
|
440
|
+
return 'unknown error';
|
|
441
|
+
try {
|
|
442
|
+
return JSON.stringify(error);
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
return 'unknown error';
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=crossmint-signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crossmint-signer.js","sourceRoot":"","sources":["../src/crossmint-signer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,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,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface CrossmintSignerConfig {
|
|
2
|
+
apiBaseUrl?: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
maxPollAttempts?: number;
|
|
5
|
+
pollIntervalMs?: number;
|
|
6
|
+
requestDelayMs?: number;
|
|
7
|
+
signer?: string;
|
|
8
|
+
/** Server signer secret (`xmsk1_<64hex>`). When set, automatically signs awaiting-approval transactions. */
|
|
9
|
+
signerSecret?: string;
|
|
10
|
+
walletLocator: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CrossmintApiError {
|
|
13
|
+
error?: unknown;
|
|
14
|
+
message?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CrossmintWalletResponse {
|
|
17
|
+
address: string;
|
|
18
|
+
chainType: string;
|
|
19
|
+
type: string;
|
|
20
|
+
}
|
|
21
|
+
export interface CrossmintCreateTransactionRequest {
|
|
22
|
+
params: {
|
|
23
|
+
signer?: string;
|
|
24
|
+
transaction: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface CrossmintTransactionOnChain {
|
|
28
|
+
transaction?: string;
|
|
29
|
+
txId?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface CrossmintTransactionApprovals {
|
|
32
|
+
pending?: Array<{
|
|
33
|
+
message?: string;
|
|
34
|
+
signer?: unknown;
|
|
35
|
+
}>;
|
|
36
|
+
submitted?: Array<{
|
|
37
|
+
signature?: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export type CrossmintTransactionStatus = 'awaiting-approval' | 'failed' | 'pending' | 'success';
|
|
41
|
+
export interface CrossmintTransactionResponse {
|
|
42
|
+
approvals?: CrossmintTransactionApprovals;
|
|
43
|
+
chainType?: string;
|
|
44
|
+
error?: unknown;
|
|
45
|
+
id: string;
|
|
46
|
+
onChain?: CrossmintTransactionOnChain;
|
|
47
|
+
status: string;
|
|
48
|
+
walletType?: string;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4GAA4G;IAC5G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iCAAiC;IAC9C,MAAM,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;CACL;AAED,MAAM,WAAW,2BAA2B;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC1C,OAAO,CAAC,EAAE,KAAK,CAAC;QACZ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACN;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhG,MAAM,WAAW,4BAA4B;IACzC,SAAS,CAAC,EAAE,6BAA6B,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,2BAA2B,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,12 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/keychain-crossmint",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
3
|
+
"author": "Solana Foundation",
|
|
4
|
+
"version": "0.6.0",
|
|
5
|
+
"description": "Crossmint wallet signer for Solana transactions",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "https://github.com/solana-foundation/solana-keychain",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"solana",
|
|
10
|
+
"signing",
|
|
11
|
+
"wallet",
|
|
12
|
+
"crossmint"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"src"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@solana/addresses": "^6.0.1",
|
|
30
|
+
"@solana/codecs-strings": "^6.0.1",
|
|
31
|
+
"@solana/keys": "^6.0.1",
|
|
32
|
+
"@solana/signers": "^6.0.1",
|
|
33
|
+
"@solana/transactions": "^6.0.1",
|
|
34
|
+
"@solana/keychain-core": "0.6.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@solana-program/memo": "^0.11.0",
|
|
38
|
+
"@solana/kit": "^6.0.1",
|
|
39
|
+
"dotenv": "^17.2.3",
|
|
40
|
+
"@solana/keychain-test-utils": "0.6.0"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
9
45
|
"scripts": {
|
|
10
|
-
"
|
|
46
|
+
"build": "tsc --build",
|
|
47
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"test:unit": "vitest run --config ../../vitest.config.unit.ts",
|
|
50
|
+
"test:integration": "vitest run --config ../../vitest.config.integration.ts",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"test:watch:unit": "vitest --config ../../vitest.config.unit.ts",
|
|
53
|
+
"test:watch:integration": "vitest --config ../../vitest.config.integration.ts",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test:treeshakability": "agadoo dist/index.js"
|
|
11
56
|
}
|
|
12
|
-
}
|
|
57
|
+
}
|