@solana/keys 5.1.0 → 5.1.1-canary-20251216194212
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/index.browser.cjs +3 -2
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +3 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.native.mjs +3 -2
- package/dist/index.native.mjs.map +1 -1
- package/dist/index.node.cjs +3 -2
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +3 -2
- package/dist/index.node.mjs.map +1 -1
- package/dist/types/signatures.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.browser.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var assertions = require('@solana/assertions');
|
|
4
4
|
var errors = require('@solana/errors');
|
|
5
|
+
var codecsCore = require('@solana/codecs-core');
|
|
5
6
|
var codecsStrings = require('@solana/codecs-strings');
|
|
6
7
|
|
|
7
8
|
// src/key-pair.ts
|
|
@@ -130,7 +131,7 @@ function isSignatureBytes(putativeSignatureBytes) {
|
|
|
130
131
|
}
|
|
131
132
|
async function signBytes(key, data) {
|
|
132
133
|
assertions.assertSigningCapabilityIsAvailable();
|
|
133
|
-
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);
|
|
134
|
+
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, codecsCore.toArrayBuffer(data));
|
|
134
135
|
return new Uint8Array(signedData);
|
|
135
136
|
}
|
|
136
137
|
function signature(putativeSignature) {
|
|
@@ -143,7 +144,7 @@ function signatureBytes(putativeSignatureBytes) {
|
|
|
143
144
|
}
|
|
144
145
|
async function verifySignature(key, signature2, data) {
|
|
145
146
|
assertions.assertVerificationCapabilityIsAvailable();
|
|
146
|
-
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature2, data);
|
|
147
|
+
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, codecsCore.toArrayBuffer(signature2), codecsCore.toArrayBuffer(data));
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
// src/key-pair.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH","assertKeyExporterIsAvailable","SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY","getBase58Encoder","SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE","SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH","assertSigningCapabilityIsAvailable","signature","assertVerificationCapabilityIsAvailable","assertKeyGenerationIsAvailable","assertPRNGIsAvailable","SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH","SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY","privateKey"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data);\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH","assertKeyExporterIsAvailable","SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY","getBase58Encoder","SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE","SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH","assertSigningCapabilityIsAvailable","toArrayBuffer","signature","assertVerificationCapabilityIsAvailable","assertKeyGenerationIsAvailable","assertPRNGIsAvailable","SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH","SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY","privateKey"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertKeyExporterIsAvailable, assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable, assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';
|
|
2
2
|
import { SolanaError, SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY } from '@solana/errors';
|
|
3
|
+
import { toArrayBuffer } from '@solana/codecs-core';
|
|
3
4
|
import { getBase58Encoder } from '@solana/codecs-strings';
|
|
4
5
|
|
|
5
6
|
// src/key-pair.ts
|
|
@@ -128,7 +129,7 @@ function isSignatureBytes(putativeSignatureBytes) {
|
|
|
128
129
|
}
|
|
129
130
|
async function signBytes(key, data) {
|
|
130
131
|
assertSigningCapabilityIsAvailable();
|
|
131
|
-
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);
|
|
132
|
+
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));
|
|
132
133
|
return new Uint8Array(signedData);
|
|
133
134
|
}
|
|
134
135
|
function signature(putativeSignature) {
|
|
@@ -141,7 +142,7 @@ function signatureBytes(putativeSignatureBytes) {
|
|
|
141
142
|
}
|
|
142
143
|
async function verifySignature(key, signature2, data) {
|
|
143
144
|
assertVerificationCapabilityIsAvailable();
|
|
144
|
-
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature2, data);
|
|
145
|
+
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature2), toArrayBuffer(data));
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
// src/key-pair.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":";;;;;;;AAAO,IAAM,4BAAA;AAAA;AAAA;AAAA,EAGT,MAAA,CAAO,MAAA,CAAO,EAAE,IAAA,EAAM,WAAW;AAAA,CAAA;ACErC,SAAS,eAAe,KAAA,EAA+C;AAEnE,EAAA,OAAO,IAAI,UAAA,CAAW;AAAA;AAAA;AAAA;AAAA,IAIlB,EAAA;AAAA;AAAA,IACA,EAAA;AAAA;AAAA,IAEI,CAAA;AAAA;AAAA,IACA,CAAA;AAAA;AAAA,IACI,CAAA;AAAA;AAAA,IAEJ,EAAA;AAAA;AAAA,IACA,CAAA;AAAA;AAAA,IACI,CAAA;AAAA;AAAA,IACA,CAAA;AAAA;AAAA;AAAA,IAEQ,EAAA;AAAA;AAAA,IACA,GAAA;AAAA;AAAA;AAAA,IAEA,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhB,CAAA;AAAA;AAAA,IACA,EAAA;AAAA;AAAA;AAAA,IAGI,CAAA;AAAA;AAAA,IACA,EAAA;AAAA;AAAA,IAEJ,GAAG;AAAA,GACN,CAAA;AACL;AAoBA,eAAsB,yBAAA,CAClB,KAAA,EACA,WAAA,GAAuB,KAAA,EACL;AAClB,EAAA,MAAM,eAAe,KAAA,CAAM,UAAA;AAC3B,EAAA,IAAI,iBAAiB,EAAA,EAAI;AACrB,IAAA,MAAM,IAAI,YAAY,mDAAA,EAAqD;AAAA,MACvE;AAAA,KACH,CAAA;AAAA,EACL;AACA,EAAA,MAAM,oBAAA,GAAuB,eAAe,KAAK,CAAA;AACjD,EAAA,OAAO,MAAM,MAAA,CAAO,MAAA,CAAO,UAAU,OAAA,EAAS,oBAAA,EAAsB,8BAA8B,WAAA,EAAa;AAAA,IAC3G;AAAA,GACH,CAAA;AACL;ACpDA,eAAsB,0BAAA,CAClB,UAAA,EACA,WAAA,GAAuB,KAAA,EACL;AAClB,EAAA,4BAAA,EAA6B;AAE7B,EAAA,IAAI,UAAA,CAAW,gBAAgB,KAAA,EAAO;AAClC,IAAA,MAAM,IAAIA,WAAAA,CAAY,8DAAA,EAAgE,EAAE,GAAA,EAAK,YAAY,CAAA;AAAA,EAC7G;AAGA,EAAA,MAAM,MAAM,MAAM,MAAA,CAAO,MAAA,CAAO,SAAA,CAAU,OAAO,UAAU,CAAA;AAG3D,EAAA,OAAO,MAAM,OAAO,MAAA,CAAO,SAAA;AAAA,IACvB,KAAA;AAAA,IACA;AAAA,MACI,GAAA,EAAiB,SAAA;AAAA,MACjB,GAAA,EAAuB,WAAA;AAAA,MACvB,OAAA,EAA8B,CAAC,QAAQ,CAAA;AAAA,MACvC,GAAA,EAAoB,KAAA;AAAA,MACpB,GAAiC,GAAA,CAAI;AAAA,KACzC;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACb;AACJ;ACxBA,IAAI,aAAA;AA8BG,SAAS,kBAAkB,iBAAA,EAAmE;AACjG,EAAA,IAAI,CAAC,aAAA,EAAe,aAAA,GAAgB,gBAAA,EAAiB;AAErD,EAAA;AAAA;AAAA,IAEI,kBAAkB,MAAA,GAAS,EAAA;AAAA,IAE3B,kBAAkB,MAAA,GAAS;AAAA,IAC7B;AACE,IAAA,MAAM,IAAIA,YAAY,wDAAA,EAA0D;AAAA,MAC5E,cAAc,iBAAA,CAAkB;AAAA,KACnC,CAAA;AAAA,EACL;AAEA,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAA,CAAO,iBAAiB,CAAA;AACpD,EAAA,sBAAA,CAAuB,KAAK,CAAA;AAChC;AA8BO,SAAS,uBACZ,sBAAA,EACgD;AAChD,EAAA,MAAM,WAAW,sBAAA,CAAuB,UAAA;AACxC,EAAA,IAAI,aAAa,EAAA,EAAI;AACjB,IAAA,MAAM,IAAIA,YAAY,iDAAA,EAAmD;AAAA,MACrE,YAAA,EAAc;AAAA,KACjB,CAAA;AAAA,EACL;AACJ;AAsBO,SAAS,YAAY,iBAAA,EAA2D;AACnF,EAAA,IAAI,CAAC,aAAA,EAAe,aAAA,GAAgB,gBAAA,EAAiB;AAGrD,EAAA;AAAA;AAAA,IAEI,kBAAkB,MAAA,GAAS,EAAA;AAAA,IAE3B,kBAAkB,MAAA,GAAS;AAAA,IAC7B;AACE,IAAA,OAAO,KAAA;AAAA,EACX;AAEA,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAA,CAAO,iBAAiB,CAAA;AACpD,EAAA,OAAO,iBAAiB,KAAK,CAAA;AACjC;AAqBO,SAAS,iBAAiB,sBAAA,EAAsF;AACnH,EAAA,OAAO,uBAAuB,UAAA,KAAe,EAAA;AACjD;AAeA,eAAsB,SAAA,CAAU,KAAgB,IAAA,EAAmD;AAC/F,EAAA,kCAAA,EAAmC;AACnC,EAAA,MAAM,aAAa,MAAM,MAAA,CAAO,OAAO,IAAA,CAAK,4BAAA,EAA8B,KAAK,IAAI,CAAA;AACnF,EAAA,OAAO,IAAI,WAAW,UAAU,CAAA;AACpC;AAgBO,SAAS,UAAU,iBAAA,EAAsC;AAC5D,EAAA,iBAAA,CAAkB,iBAAiB,CAAA;AACnC,EAAA,OAAO,iBAAA;AACX;AAgBO,SAAS,eAAe,sBAAA,EAA4D;AACvF,EAAA,sBAAA,CAAuB,sBAAsB,CAAA;AAC7C,EAAA,OAAO,sBAAA;AACX;AAkBA,eAAsB,eAAA,CAClB,GAAA,EACAC,UAAAA,EACA,IAAA,EACgB;AAChB,EAAA,uCAAA,EAAwC;AACxC,EAAA,OAAO,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,4BAAA,EAA8B,GAAA,EAAKA,YAAW,IAAI,CAAA;AACxF;;;ACpOA,eAAsB,eAAA,GAA0C;AAC5D,EAAA,MAAM,8BAAA,EAA+B;AACrC,EAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,MAAA,CAAO,WAAA;AAAA;AAAA,IAChB,4BAAA;AAAA;AAAA;AAAA,IACE,KAAA;AAAA;AAAA;AAAA,IACC,CAAC,QAAQ,QAAQ;AAAA,GACxC;AACA,EAAA,OAAO,OAAA;AACX;AA0BA,eAAsB,sBAAA,CAClB,KAAA,EACA,WAAA,GAAuB,KAAA,EACD;AACtB,EAAA,qBAAA,EAAsB;AAEtB,EAAA,IAAI,KAAA,CAAM,eAAe,EAAA,EAAI;AACzB,IAAA,MAAM,IAAID,WAAAA,CAAY,gDAAA,EAAkD,EAAE,UAAA,EAAY,KAAA,CAAM,YAAY,CAAA;AAAA,EAC5G;AACA,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAC9C,OAAO,MAAA,CAAO,SAAA;AAAA,MAAU,KAAA;AAAA,MAAO,KAAA,CAAM,MAAM,EAAE,CAAA;AAAA,MAAG,4BAAA;AAAA;AAAA,MAAgD,IAAA;AAAA,MAAM;AAAA,QAClG;AAAA;AACJ,KAAC;AAAA,IACD,0BAA0B,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,GAAG,WAAW;AAAA,GAC5D,CAAA;AAGD,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,EAAE,CAAA;AACrC,EAAA,MAAA,CAAO,gBAAgB,WAAW,CAAA;AAClC,EAAA,MAAM,UAAA,GAAa,MAAM,SAAA,CAAU,UAAA,EAAY,WAAW,CAAA;AAC1D,EAAA,MAAM,OAAA,GAAU,MAAM,eAAA,CAAgB,SAAA,EAAW,YAAY,WAAW,CAAA;AACxE,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA,MAAM,IAAIA,YAAY,qDAAqD,CAAA;AAAA,EAC/E;AAEA,EAAA,OAAO,EAAE,YAAY,SAAA,EAAU;AACnC;AAiCA,eAAsB,gCAAA,CAClB,KAAA,EACA,WAAA,GAAuB,KAAA,EACD;AACtB,EAAA,MAAM,iBAAA,GAAoB,yBAAA,CAA0B,KAAA,EAAO,WAAW,CAAA;AAOtE,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA;AAAA;AAAA;AAAA,IAAA,CAI7C,cAAc,iBAAA,GAAoB,yBAAA;AAAA,MAA0B,KAAA;AAAA,MAAO;AAAA;AAAA,KAAsB,EAAG,IAAA;AAAA,MACzF,OAAME,gBAAc,MAAM,0BAAA;AAAA,QAA2BA,WAAAA;AAAA,QAAY;AAAA;AAAA;AAAsB,KAC3F;AAAA,IACA;AAAA,GACH,CAAA;AAED,EAAA,OAAO,EAAE,YAAY,SAAA,EAAU;AACnC","file":"index.browser.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data);\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
package/dist/index.native.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertKeyExporterIsAvailable, assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable, assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';
|
|
2
2
|
import { SolanaError, SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY } from '@solana/errors';
|
|
3
|
+
import { toArrayBuffer } from '@solana/codecs-core';
|
|
3
4
|
import { getBase58Encoder } from '@solana/codecs-strings';
|
|
4
5
|
|
|
5
6
|
// src/key-pair.ts
|
|
@@ -128,7 +129,7 @@ function isSignatureBytes(putativeSignatureBytes) {
|
|
|
128
129
|
}
|
|
129
130
|
async function signBytes(key, data) {
|
|
130
131
|
assertSigningCapabilityIsAvailable();
|
|
131
|
-
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);
|
|
132
|
+
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));
|
|
132
133
|
return new Uint8Array(signedData);
|
|
133
134
|
}
|
|
134
135
|
function signature(putativeSignature) {
|
|
@@ -141,7 +142,7 @@ function signatureBytes(putativeSignatureBytes) {
|
|
|
141
142
|
}
|
|
142
143
|
async function verifySignature(key, signature2, data) {
|
|
143
144
|
assertVerificationCapabilityIsAvailable();
|
|
144
|
-
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature2, data);
|
|
145
|
+
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature2), toArrayBuffer(data));
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
// src/key-pair.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data);\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
package/dist/index.node.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var assertions = require('@solana/assertions');
|
|
4
4
|
var errors = require('@solana/errors');
|
|
5
|
+
var codecsCore = require('@solana/codecs-core');
|
|
5
6
|
var codecsStrings = require('@solana/codecs-strings');
|
|
6
7
|
|
|
7
8
|
// src/key-pair.ts
|
|
@@ -130,7 +131,7 @@ function isSignatureBytes(putativeSignatureBytes) {
|
|
|
130
131
|
}
|
|
131
132
|
async function signBytes(key, data) {
|
|
132
133
|
assertions.assertSigningCapabilityIsAvailable();
|
|
133
|
-
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);
|
|
134
|
+
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, codecsCore.toArrayBuffer(data));
|
|
134
135
|
return new Uint8Array(signedData);
|
|
135
136
|
}
|
|
136
137
|
function signature(putativeSignature) {
|
|
@@ -143,7 +144,7 @@ function signatureBytes(putativeSignatureBytes) {
|
|
|
143
144
|
}
|
|
144
145
|
async function verifySignature(key, signature2, data) {
|
|
145
146
|
assertions.assertVerificationCapabilityIsAvailable();
|
|
146
|
-
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature2, data);
|
|
147
|
+
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, codecsCore.toArrayBuffer(signature2), codecsCore.toArrayBuffer(data));
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
// src/key-pair.ts
|
package/dist/index.node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH","assertKeyExporterIsAvailable","SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY","getBase58Encoder","SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE","SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH","assertSigningCapabilityIsAvailable","signature","assertVerificationCapabilityIsAvailable","assertKeyGenerationIsAvailable","assertPRNGIsAvailable","SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH","SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY","privateKey"],"mappings":"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","file":"index.node.cjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data);\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH","assertKeyExporterIsAvailable","SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY","getBase58Encoder","SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE","SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH","assertSigningCapabilityIsAvailable","toArrayBuffer","signature","assertVerificationCapabilityIsAvailable","assertKeyGenerationIsAvailable","assertPRNGIsAvailable","SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH","SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY","privateKey"],"mappings":"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","file":"index.node.cjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
package/dist/index.node.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertKeyExporterIsAvailable, assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable, assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';
|
|
2
2
|
import { SolanaError, SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY } from '@solana/errors';
|
|
3
|
+
import { toArrayBuffer } from '@solana/codecs-core';
|
|
3
4
|
import { getBase58Encoder } from '@solana/codecs-strings';
|
|
4
5
|
|
|
5
6
|
// src/key-pair.ts
|
|
@@ -128,7 +129,7 @@ function isSignatureBytes(putativeSignatureBytes) {
|
|
|
128
129
|
}
|
|
129
130
|
async function signBytes(key, data) {
|
|
130
131
|
assertSigningCapabilityIsAvailable();
|
|
131
|
-
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);
|
|
132
|
+
const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));
|
|
132
133
|
return new Uint8Array(signedData);
|
|
133
134
|
}
|
|
134
135
|
function signature(putativeSignature) {
|
|
@@ -141,7 +142,7 @@ function signatureBytes(putativeSignatureBytes) {
|
|
|
141
142
|
}
|
|
142
143
|
async function verifySignature(key, signature2, data) {
|
|
143
144
|
assertVerificationCapabilityIsAvailable();
|
|
144
|
-
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature2, data);
|
|
145
|
+
return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature2), toArrayBuffer(data));
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
// src/key-pair.ts
|
package/dist/index.node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":"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","file":"index.node.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data);\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data);\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/algorithm.ts","../src/private-key.ts","../src/public-key.ts","../src/signatures.ts","../src/key-pair.ts"],"names":["SolanaError","signature","privateKey"],"mappings":"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","file":"index.node.mjs","sourcesContent":["export const ED25519_ALGORITHM_IDENTIFIER =\n // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n Object.freeze({ name: 'Ed25519' });\n","import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n const actualLength = bytes.byteLength;\n if (actualLength !== 32) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n actualLength,\n });\n }\n const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n 'sign',\n ]);\n}\n","import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n privateKey: CryptoKey,\n extractable: boolean = false,\n): Promise<CryptoKey> {\n assertKeyExporterIsAvailable();\n\n if (privateKey.extractable === false) {\n throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n }\n\n // Export private key.\n const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n // Import public key.\n return await crypto.subtle.importKey(\n 'jwk',\n {\n crv /* curve */: 'Ed25519',\n ext /* extractable */: extractable,\n key_ops /* key operations */: ['verify'],\n kty /* key type */: 'OKP' /* octet key pair */,\n x /* public key x-coordinate */: jwk.x,\n },\n 'Ed25519',\n extractable,\n ['verify'],\n );\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n * // We know only that what the user typed conforms to the `string` type.\n * const signature: string = signatureInput.value;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signature` to `Signature`.\n * assertIsSignature(signature);\n * // At this point, `signature` is a `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * } catch (e) {\n * // `signature` turned out not to be a base58-encoded signature\n * }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n actualLength: putativeSignature.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n * // We know only that the input conforms to the `ReadonlyUint8Array` type.\n * const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n * assertIsSignatureBytes(signatureBytes);\n * // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } catch (e) {\n * // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n * }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n const numBytes = putativeSignatureBytes.byteLength;\n if (numBytes !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n * // At this point, `signature` has been refined to a\n * // `Signature` that can be used with the RPC.\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * setSignatureStatus(status);\n * } else {\n * setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest value (64 bytes of zeroes)\n putativeSignature.length < 64 ||\n // Highest value (64 bytes of 255)\n putativeSignature.length > 88\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const bytes = base58Encoder.encode(putativeSignature);\n return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n * // At this point, `signatureBytes` has been refined to a\n * // `SignatureBytes` that can be used with `verifySignature`.\n * if (!(await verifySignature(publicKey, signatureBytes, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * } else {\n * setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n * value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n assertIsSignature(putativeSignature);\n return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n assertIsSignatureBytes(putativeSignatureBytes);\n return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n * throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n key: CryptoKey,\n signature: SignatureBytes,\n data: ReadonlyUint8Array,\n): Promise<boolean> {\n assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n","import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n /* extractable */ false, // Prevents the bytes of the private key from being visible to JS.\n /* allowed uses */ ['sign', 'verify'],\n );\n return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n */\nexport async function createKeyPairFromBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n assertPRNGIsAvailable();\n\n if (bytes.byteLength !== 64) {\n throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n }\n const [publicKey, privateKey] = await Promise.all([\n crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n 'verify',\n ]),\n createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n ]);\n\n // Verify the key pair\n const randomBytes = new Uint8Array(32);\n crypto.getRandomValues(randomBytes);\n const signedData = await signBytes(privateKey, randomBytes);\n const isValid = await verifySignature(publicKey, signedData, randomBytes);\n if (!isValid) {\n throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n }\n\n return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n // Here we need the private key to be extractable in order to export\n // it as a public key. Therefore, if the `extractable` parameter\n // is `false`, we need to create two private keys such that:\n // - The extractable one is used to create the public key and\n // - The non-extractable one is the one we will return.\n const [publicKey, privateKey] = await Promise.all([\n // This nested promise makes things efficient by\n // creating the public key in parallel with the\n // second private key creation, if it is needed.\n (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n ),\n privateKeyPromise,\n ]);\n\n return { privateKey, publicKey };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../src/signatures.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,kBAAkB,
|
|
1
|
+
{"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../src/signatures.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,kBAAkB,EAAiB,MAAM,qBAAqB,CAAC;AAOjF,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI7D;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;AAC5E;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAIjE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,IAAI,SAAS,CAgBnG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,sBAAsB,CAClC,sBAAsB,EAAE,kBAAkB,GAC3C,OAAO,CAAC,sBAAsB,IAAI,cAAc,CAOlD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,iBAAiB,EAAE,MAAM,GAAG,iBAAiB,IAAI,SAAS,CAerF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,sBAAsB,EAAE,kBAAkB,GAAG,sBAAsB,IAAI,cAAc,CAErH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAIjG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAG9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,sBAAsB,EAAE,kBAAkB,GAAG,cAAc,CAGzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACjC,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,kBAAkB,GACzB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/keys",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.1-canary-20251216194212",
|
|
4
4
|
"description": "Helpers for generating and transforming key material",
|
|
5
5
|
"homepage": "https://www.solanakit.com/api#solanakeys",
|
|
6
6
|
"exports": {
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
"maintained node versions"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@solana/assertions": "5.1.
|
|
59
|
-
"@solana/codecs-core": "5.1.
|
|
60
|
-
"@solana/
|
|
61
|
-
"@solana/
|
|
62
|
-
"@solana/
|
|
58
|
+
"@solana/assertions": "5.1.1-canary-20251216194212",
|
|
59
|
+
"@solana/codecs-core": "5.1.1-canary-20251216194212",
|
|
60
|
+
"@solana/codecs-strings": "5.1.1-canary-20251216194212",
|
|
61
|
+
"@solana/errors": "5.1.1-canary-20251216194212",
|
|
62
|
+
"@solana/nominal-types": "5.1.1-canary-20251216194212"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"typescript": ">=5.3.3"
|