Add extractable option to generateKeyPair and generateKeyPairSigner#1531
Conversation
…ner` This PR adds an optional `extractable` boolean argument to `generateKeyPair` in `@solana/keys` and threads it through `generateKeyPairSigner` in `@solana/signers`. The argument defaults to `false`, preserving the existing secure-by-default behavior that prevents the bytes of the private key from being visible to JS. When set to `true`, the generated private key can be exported via `crypto.subtle.exportKey()`, which is useful for scenarios like persisting a generated key pair. This brings `generateKeyPair` and `generateKeyPairSigner` in line with the sibling helpers `createKeyPairFromBytes`, `createKeyPairFromPrivateKeyBytes`, `createKeyPairSignerFromBytes`, and `createKeyPairSignerFromPrivateKeyBytes`, which already accept an `extractable` parameter.
🦋 Changeset detectedLatest commit: 9c43c16 The changes in this PR will be included in the next version bump. This PR includes changesets to release 46 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
BundleMonFiles updated (3)
Unchanged files (139)
Total files change -79B -0.02% Final result: ✅ View report in BundleMon website ➡️ |
trevor-cortex
left a comment
There was a problem hiding this comment.
Summary
Adds an optional extractable: boolean = false parameter to generateKeyPair (@solana/keys) and threads it through generateKeyPairSigner (@solana/signers). When true, the generated Ed25519 private key can be exported via crypto.subtle.exportKey(). The default remains false, preserving the existing secure-by-default behavior.
This aligns the signatures of generateKeyPair / generateKeyPairSigner with their sibling helpers (createKeyPairFromBytes, createKeyPairFromPrivateKeyBytes, createKeyPairSignerFromBytes, createKeyPairSignerFromPrivateKeyBytes), which already expose the same flag with the same default.
What to watch out for
- Backwards compatible: the new parameter is optional and defaults to
false, so existing call sites keep their current (non-extractable) behavior. The changeset is correctly marked as aminorbump for both packages. - Secure-by-default preserved: the old inline comment "Prevents the bytes of the private key from being visible to JS" is now captured in the TSDoc for the
extractableparameter, so the security rationale isn't lost. - Consistency: parameter name, default, and TSDoc wording match the sibling helpers in
packages/keys/src/key-pair.ts.
Test coverage
packages/keys/src/__tests__/key-pair-test.tsadds two cases: explicitfalseand explicittrue, asserting the resultingprivateKey.extractableflag.packages/signers/src/__tests__/keypair-signer-test.tsupdates the existing default-call test to additionally assertgenerateKeyPairwas called withfalse, and adds a new test verifying thatgenerateKeyPairSigner(true)forwardstruetogenerateKeyPair.
Notes for subsequent reviewers
- Worth a quick sanity check that the docs site / API reference picks up the new
@param extractableTSDoc block for both functions. - No runtime changes beyond the new parameter pass-through — the
crypto.subtle.generateKeycall now receivesextractabledirectly instead of a hardcodedfalse, which is the only behavioral change.
Looks good to me. 🚀
|
Documentation Preview: https://kit-docs-i95fbygaw-anza-tech.vercel.app |
|
Super happy to finally see this as I think it means I can update my answer here 🙏 |
|
@beeman Yeah the other factory helpers already have that |
|
@lorisleiva amazing! Way better that these are part of the official package so that people don't have to write ad-hoc implementations of this. 🙏 |
mcintyre94
left a comment
There was a problem hiding this comment.
I'm happy with this, I think it makes sense to have as an option, with false as the default
I think the argument not to do this would be that with the FromBytes helpers, you already have the bytes in insecure JS when you call it, so extracting doesn't add any additional risk. Whereas when you generate, assuming a sane browser implementation, those bytes are never available insecurely.
That said if you have malicious JS in your sandbox (browser extension etc) then it can hijack the crypto APIs anyway so I don't think anything we can do actually holds up to that threat.
|
🔎💬 Inkeep AI search and chat service is syncing content for source 'Solana Kit Docs' |
|
Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up. |

This PR adds an optional
extractableboolean argument togenerateKeyPairin@solana/keysand threads it throughgenerateKeyPairSignerin@solana/signers. The argument defaults tofalse, preserving the existing secure-by-default behavior that prevents the bytes of the private key from being visible to JS. When set totrue, the generated private key can be exported viacrypto.subtle.exportKey(), which is useful for scenarios like persisting a generated key pair. This bringsgenerateKeyPairandgenerateKeyPairSignerin line with the sibling helperscreateKeyPairFromBytes,createKeyPairFromPrivateKeyBytes,createKeyPairSignerFromBytes, andcreateKeyPairSignerFromPrivateKeyBytes, which already accept anextractableparameter.