@solana/keys 2.0.0-experimental.ee9f3d8 → 2.0.0-experimental.f040ea3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -31
- package/dist/index.browser.cjs +12 -102
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +10 -98
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +24 -321
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +10 -87
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +12 -91
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +10 -87
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +8 -6
- package/dist/types/index.d.ts +1 -2
- package/dist/types/signatures.d.ts +6 -0
- package/package.json +14 -17
- package/dist/types/base58.d.ts +0 -10
- package/dist/types/guard.d.ts +0 -5
- package/dist/types/pubkey.d.ts +0 -3
package/README.md
CHANGED
|
@@ -18,55 +18,44 @@ This package contains utilities for validating, generating, and manipulating add
|
|
|
18
18
|
|
|
19
19
|
## Types
|
|
20
20
|
|
|
21
|
-
### `
|
|
21
|
+
### `Ed25519Signature`
|
|
22
22
|
|
|
23
|
-
This type represents a
|
|
23
|
+
This type represents a 64-byte Ed25519 signature of some data with a private key.
|
|
24
24
|
|
|
25
|
-
Whenever you need to
|
|
25
|
+
Whenever you need to verify that a particular signature is, in fact, the one that would have been produced by signing some known bytes using the private key associated with some known public key, use the `verifySignature()` function in this package.
|
|
26
26
|
|
|
27
27
|
## Functions
|
|
28
28
|
|
|
29
|
-
### `
|
|
30
|
-
|
|
31
|
-
Client applications primarily deal with addresses and public keys in the form of base58-encoded strings. Addresses and public keys returned from the RPC API conform to the type `Base58EncodedAddress`. You can use a value of that type wherever a base58-encoded address or key is expected.
|
|
29
|
+
### `generateKeyPair()`
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
Generates an Ed25519 public/private key pair for use with other methods in this package that accept `CryptoKey` objects.
|
|
34
32
|
|
|
35
33
|
```ts
|
|
36
|
-
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
function handleSubmit() {
|
|
40
|
-
// We know only that what the user typed conforms to the `string` type.
|
|
41
|
-
const address: string = accountAddressInput.value;
|
|
42
|
-
try {
|
|
43
|
-
// If this type assertion function doesn't throw, then
|
|
44
|
-
// Typescript will upcast `address` to `Base58EncodedAddress`.
|
|
45
|
-
assertIsBase58EncodedAddress(address);
|
|
46
|
-
// At this point, `address` is a `Base58EncodedAddress` that can be used with the RPC.
|
|
47
|
-
const balanceInLamports = await rpc.getBalance(address).send();
|
|
48
|
-
} catch (e) {
|
|
49
|
-
// `address` turned out not to be a base58-encoded address
|
|
50
|
-
}
|
|
51
|
-
}
|
|
34
|
+
import { generateKeyPair } from '@solana/keys';
|
|
35
|
+
|
|
36
|
+
const { privateKey, publicKey } = await generateKeyPair();
|
|
52
37
|
```
|
|
53
38
|
|
|
54
|
-
### `
|
|
39
|
+
### `signBytes()`
|
|
55
40
|
|
|
56
|
-
|
|
41
|
+
Given a private `CryptoKey` and a `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a `Uint8Array`.
|
|
57
42
|
|
|
58
43
|
```ts
|
|
59
|
-
import {
|
|
44
|
+
import { signBytes } from '@solana/keys';
|
|
60
45
|
|
|
61
|
-
const
|
|
46
|
+
const data = new Uint8Array([1, 2, 3]);
|
|
47
|
+
const signature = await signBytes(privateKey, data);
|
|
62
48
|
```
|
|
63
49
|
|
|
64
|
-
### `
|
|
50
|
+
### `verifySignature()`
|
|
65
51
|
|
|
66
|
-
Given a public `CryptoKey`, this method will return
|
|
52
|
+
Given a public `CryptoKey`, an `Ed25519Signature`, and a `Uint8Array` of bytes, this method will return `true` if the signature was produced by signing the bytes using the private key associated with the public key, and `false` otherwise.
|
|
67
53
|
|
|
68
54
|
```ts
|
|
69
|
-
import {
|
|
55
|
+
import { verifySignature } from '@solana/keys';
|
|
70
56
|
|
|
71
|
-
const
|
|
57
|
+
const data = new Uint8Array([1, 2, 3]);
|
|
58
|
+
if (!(await verifySignature(publicKey, signature, data))) {
|
|
59
|
+
throw new Error('The data were *not* signed by the private key associated with `publicKey`');
|
|
60
|
+
}
|
|
72
61
|
```
|
package/dist/index.browser.cjs
CHANGED
|
@@ -1,96 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
// ../build-scripts/env-shim.ts
|
|
6
|
-
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
7
|
-
function assertIsBase58EncodedAddress(putativeBase58EncodedAddress) {
|
|
8
|
-
try {
|
|
9
|
-
if (
|
|
10
|
-
// Lowest address (32 bytes of zeroes)
|
|
11
|
-
putativeBase58EncodedAddress.length < 32 || // Highest address (32 bytes of 255)
|
|
12
|
-
putativeBase58EncodedAddress.length > 44
|
|
13
|
-
) {
|
|
14
|
-
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
15
|
-
}
|
|
16
|
-
const bytes = umiSerializers.base58.serialize(putativeBase58EncodedAddress);
|
|
17
|
-
const numBytes = bytes.byteLength;
|
|
18
|
-
if (numBytes !== 32) {
|
|
19
|
-
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
20
|
-
}
|
|
21
|
-
} catch (e) {
|
|
22
|
-
throw new Error(`\`${putativeBase58EncodedAddress}\` is not a base-58 encoded address`, {
|
|
23
|
-
cause: e
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function getBase58EncodedAddressCodec(config) {
|
|
28
|
-
return umiSerializers.string({
|
|
29
|
-
description: config?.description ?? (__DEV__ ? "A 32-byte account address" : ""),
|
|
30
|
-
encoding: umiSerializers.base58,
|
|
31
|
-
size: 32
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
function getBase58EncodedAddressComparator() {
|
|
35
|
-
return new Intl.Collator("en", {
|
|
36
|
-
caseFirst: "lower",
|
|
37
|
-
ignorePunctuation: false,
|
|
38
|
-
localeMatcher: "best fit",
|
|
39
|
-
numeric: false,
|
|
40
|
-
sensitivity: "variant",
|
|
41
|
-
usage: "sort"
|
|
42
|
-
}).compare;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// src/guard.ts
|
|
46
|
-
function assertIsSecureContext() {
|
|
47
|
-
if (!globalThis.isSecureContext) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
"Cryptographic operations are only allowed in secure browser contexts. Read more here: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts"
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
var cachedEd25519Decision;
|
|
54
|
-
async function isEd25519CurveSupported(subtle) {
|
|
55
|
-
if (cachedEd25519Decision === void 0) {
|
|
56
|
-
cachedEd25519Decision = new Promise((resolve) => {
|
|
57
|
-
subtle.generateKey(
|
|
58
|
-
"Ed25519",
|
|
59
|
-
/* extractable */
|
|
60
|
-
false,
|
|
61
|
-
["sign", "verify"]
|
|
62
|
-
).catch(() => {
|
|
63
|
-
resolve(cachedEd25519Decision = false);
|
|
64
|
-
}).then(() => {
|
|
65
|
-
resolve(cachedEd25519Decision = true);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
if (typeof cachedEd25519Decision === "boolean") {
|
|
70
|
-
return cachedEd25519Decision;
|
|
71
|
-
} else {
|
|
72
|
-
return await cachedEd25519Decision;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
async function assertKeyGenerationIsAvailable() {
|
|
76
|
-
assertIsSecureContext();
|
|
77
|
-
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.generateKey !== "function") {
|
|
78
|
-
throw new Error("No key generation implementation could be found");
|
|
79
|
-
}
|
|
80
|
-
if (!await isEd25519CurveSupported(globalThis.crypto.subtle)) {
|
|
81
|
-
throw new Error("This runtime does not support the generation of Ed25519 keypairs");
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
async function assertKeyExporterIsAvailable() {
|
|
85
|
-
assertIsSecureContext();
|
|
86
|
-
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.exportKey !== "function") {
|
|
87
|
-
throw new Error("No key export implementation could be found");
|
|
88
|
-
}
|
|
89
|
-
}
|
|
3
|
+
var assertions = require('@solana/assertions');
|
|
90
4
|
|
|
91
5
|
// src/key-pair.ts
|
|
92
6
|
async function generateKeyPair() {
|
|
93
|
-
await assertKeyGenerationIsAvailable();
|
|
7
|
+
await assertions.assertKeyGenerationIsAvailable();
|
|
94
8
|
const keyPair = await crypto.subtle.generateKey(
|
|
95
9
|
/* algorithm */
|
|
96
10
|
"Ed25519",
|
|
@@ -103,22 +17,18 @@ async function generateKeyPair() {
|
|
|
103
17
|
);
|
|
104
18
|
return keyPair;
|
|
105
19
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const [base58EncodedAddress] = getBase58EncodedAddressCodec().deserialize(new Uint8Array(publicKeyBytes));
|
|
115
|
-
return base58EncodedAddress;
|
|
20
|
+
async function signBytes(key, data) {
|
|
21
|
+
await assertions.assertSigningCapabilityIsAvailable();
|
|
22
|
+
const signedData = await crypto.subtle.sign("Ed25519", key, data);
|
|
23
|
+
return new Uint8Array(signedData);
|
|
24
|
+
}
|
|
25
|
+
async function verifySignature(key, signature, data) {
|
|
26
|
+
await assertions.assertVerificationCapabilityIsAvailable();
|
|
27
|
+
return await crypto.subtle.verify("Ed25519", key, signature, data);
|
|
116
28
|
}
|
|
117
29
|
|
|
118
|
-
exports.assertIsBase58EncodedAddress = assertIsBase58EncodedAddress;
|
|
119
30
|
exports.generateKeyPair = generateKeyPair;
|
|
120
|
-
exports.
|
|
121
|
-
exports.
|
|
122
|
-
exports.getBase58EncodedAddressFromPublicKey = getBase58EncodedAddressFromPublicKey;
|
|
31
|
+
exports.signBytes = signBytes;
|
|
32
|
+
exports.verifySignature = verifySignature;
|
|
123
33
|
//# sourceMappingURL=out.js.map
|
|
124
34
|
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["../src/key-pair.ts","../src/signatures.ts"],"names":[],"mappings":";AAAA,SAAS,sCAAsC;AAE/C,eAAsB,kBAA0C;AAC5D,QAAM,+BAA+B;AACrC,QAAM,UAAU,MAAM,OAAO,OAAO;AAAA;AAAA,IAChB;AAAA;AAAA;AAAA,IACE;AAAA;AAAA;AAAA,IACC,CAAC,QAAQ,QAAQ;AAAA,EACxC;AACA,SAAO;AACX;;;ACVA,SAAS,oCAAoC,+CAA+C;AAI5F,eAAsB,UAAU,KAAgB,MAA6C;AACzF,QAAM,mCAAmC;AACzC,QAAM,aAAa,MAAM,OAAO,OAAO,KAAK,WAAW,KAAK,IAAI;AAChE,SAAO,IAAI,WAAW,UAAU;AACpC;AAEA,eAAsB,gBAAgB,KAAgB,WAA6B,MAAoC;AACnH,QAAM,wCAAwC;AAC9C,SAAO,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,WAAW,IAAI;AACrE","sourcesContent":["import { assertKeyGenerationIsAvailable } from '@solana/assertions';\n\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ 'Ed25519', // 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 as CryptoKeyPair;\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\n\nexport type Ed25519Signature = Uint8Array & { readonly __brand: unique symbol };\n\nexport async function signBytes(key: CryptoKey, data: Uint8Array): Promise<Ed25519Signature> {\n await assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign('Ed25519', key, data);\n return new Uint8Array(signedData) as Ed25519Signature;\n}\n\nexport async function verifySignature(key: CryptoKey, signature: Ed25519Signature, data: Uint8Array): Promise<boolean> {\n await assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify('Ed25519', key, signature, data);\n}\n"]}
|
package/dist/index.browser.js
CHANGED
|
@@ -1,90 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
// ../build-scripts/env-shim.ts
|
|
4
|
-
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
5
|
-
function assertIsBase58EncodedAddress(putativeBase58EncodedAddress) {
|
|
6
|
-
try {
|
|
7
|
-
if (
|
|
8
|
-
// Lowest address (32 bytes of zeroes)
|
|
9
|
-
putativeBase58EncodedAddress.length < 32 || // Highest address (32 bytes of 255)
|
|
10
|
-
putativeBase58EncodedAddress.length > 44
|
|
11
|
-
) {
|
|
12
|
-
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
13
|
-
}
|
|
14
|
-
const bytes = base58.serialize(putativeBase58EncodedAddress);
|
|
15
|
-
const numBytes = bytes.byteLength;
|
|
16
|
-
if (numBytes !== 32) {
|
|
17
|
-
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
18
|
-
}
|
|
19
|
-
} catch (e) {
|
|
20
|
-
throw new Error(`\`${putativeBase58EncodedAddress}\` is not a base-58 encoded address`, {
|
|
21
|
-
cause: e
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function getBase58EncodedAddressCodec(config) {
|
|
26
|
-
return string({
|
|
27
|
-
description: config?.description ?? (__DEV__ ? "A 32-byte account address" : ""),
|
|
28
|
-
encoding: base58,
|
|
29
|
-
size: 32
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
function getBase58EncodedAddressComparator() {
|
|
33
|
-
return new Intl.Collator("en", {
|
|
34
|
-
caseFirst: "lower",
|
|
35
|
-
ignorePunctuation: false,
|
|
36
|
-
localeMatcher: "best fit",
|
|
37
|
-
numeric: false,
|
|
38
|
-
sensitivity: "variant",
|
|
39
|
-
usage: "sort"
|
|
40
|
-
}).compare;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// src/guard.ts
|
|
44
|
-
function assertIsSecureContext() {
|
|
45
|
-
if (!globalThis.isSecureContext) {
|
|
46
|
-
throw new Error(
|
|
47
|
-
"Cryptographic operations are only allowed in secure browser contexts. Read more here: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts"
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
var cachedEd25519Decision;
|
|
52
|
-
async function isEd25519CurveSupported(subtle) {
|
|
53
|
-
if (cachedEd25519Decision === void 0) {
|
|
54
|
-
cachedEd25519Decision = new Promise((resolve) => {
|
|
55
|
-
subtle.generateKey(
|
|
56
|
-
"Ed25519",
|
|
57
|
-
/* extractable */
|
|
58
|
-
false,
|
|
59
|
-
["sign", "verify"]
|
|
60
|
-
).catch(() => {
|
|
61
|
-
resolve(cachedEd25519Decision = false);
|
|
62
|
-
}).then(() => {
|
|
63
|
-
resolve(cachedEd25519Decision = true);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (typeof cachedEd25519Decision === "boolean") {
|
|
68
|
-
return cachedEd25519Decision;
|
|
69
|
-
} else {
|
|
70
|
-
return await cachedEd25519Decision;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function assertKeyGenerationIsAvailable() {
|
|
74
|
-
assertIsSecureContext();
|
|
75
|
-
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.generateKey !== "function") {
|
|
76
|
-
throw new Error("No key generation implementation could be found");
|
|
77
|
-
}
|
|
78
|
-
if (!await isEd25519CurveSupported(globalThis.crypto.subtle)) {
|
|
79
|
-
throw new Error("This runtime does not support the generation of Ed25519 keypairs");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
async function assertKeyExporterIsAvailable() {
|
|
83
|
-
assertIsSecureContext();
|
|
84
|
-
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.exportKey !== "function") {
|
|
85
|
-
throw new Error("No key export implementation could be found");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
1
|
+
import { assertKeyGenerationIsAvailable, assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';
|
|
88
2
|
|
|
89
3
|
// src/key-pair.ts
|
|
90
4
|
async function generateKeyPair() {
|
|
@@ -101,18 +15,16 @@ async function generateKeyPair() {
|
|
|
101
15
|
);
|
|
102
16
|
return keyPair;
|
|
103
17
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const [base58EncodedAddress] = getBase58EncodedAddressCodec().deserialize(new Uint8Array(publicKeyBytes));
|
|
113
|
-
return base58EncodedAddress;
|
|
18
|
+
async function signBytes(key, data) {
|
|
19
|
+
await assertSigningCapabilityIsAvailable();
|
|
20
|
+
const signedData = await crypto.subtle.sign("Ed25519", key, data);
|
|
21
|
+
return new Uint8Array(signedData);
|
|
22
|
+
}
|
|
23
|
+
async function verifySignature(key, signature, data) {
|
|
24
|
+
await assertVerificationCapabilityIsAvailable();
|
|
25
|
+
return await crypto.subtle.verify("Ed25519", key, signature, data);
|
|
114
26
|
}
|
|
115
27
|
|
|
116
|
-
export {
|
|
28
|
+
export { generateKeyPair, signBytes, verifySignature };
|
|
117
29
|
//# sourceMappingURL=out.js.map
|
|
118
30
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["../src/key-pair.ts","../src/signatures.ts"],"names":[],"mappings":";AAAA,SAAS,sCAAsC;AAE/C,eAAsB,kBAA0C;AAC5D,QAAM,+BAA+B;AACrC,QAAM,UAAU,MAAM,OAAO,OAAO;AAAA;AAAA,IAChB;AAAA;AAAA;AAAA,IACE;AAAA;AAAA;AAAA,IACC,CAAC,QAAQ,QAAQ;AAAA,EACxC;AACA,SAAO;AACX;;;ACVA,SAAS,oCAAoC,+CAA+C;AAI5F,eAAsB,UAAU,KAAgB,MAA6C;AACzF,QAAM,mCAAmC;AACzC,QAAM,aAAa,MAAM,OAAO,OAAO,KAAK,WAAW,KAAK,IAAI;AAChE,SAAO,IAAI,WAAW,UAAU;AACpC;AAEA,eAAsB,gBAAgB,KAAgB,WAA6B,MAAoC;AACnH,QAAM,wCAAwC;AAC9C,SAAO,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,WAAW,IAAI;AACrE","sourcesContent":["import { assertKeyGenerationIsAvailable } from '@solana/assertions';\n\nexport async function generateKeyPair(): Promise<CryptoKeyPair> {\n await assertKeyGenerationIsAvailable();\n const keyPair = await crypto.subtle.generateKey(\n /* algorithm */ 'Ed25519', // 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 as CryptoKeyPair;\n}\n","import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\n\nexport type Ed25519Signature = Uint8Array & { readonly __brand: unique symbol };\n\nexport async function signBytes(key: CryptoKey, data: Uint8Array): Promise<Ed25519Signature> {\n await assertSigningCapabilityIsAvailable();\n const signedData = await crypto.subtle.sign('Ed25519', key, data);\n return new Uint8Array(signedData) as Ed25519Signature;\n}\n\nexport async function verifySignature(key: CryptoKey, signature: Ed25519Signature, data: Uint8Array): Promise<boolean> {\n await assertVerificationCapabilityIsAvailable();\n return await crypto.subtle.verify('Ed25519', key, signature, data);\n}\n"]}
|