@solana/web3.js 1.53.0 → 1.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.browser.cjs.js +459 -1825
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +455 -1826
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +462 -1847
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +114 -12
- package/lib/index.esm.js +458 -1848
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +19272 -25771
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +8 -5
- package/lib/index.iife.min.js.map +1 -1
- package/lib/index.native.js +459 -1824
- package/lib/index.native.js.map +1 -1
- package/package.json +5 -7
- package/src/account.ts +18 -9
- package/src/connection.ts +11 -9
- package/src/keypair.ts +19 -24
- package/src/layout.ts +7 -0
- package/src/message/index.ts +19 -6
- package/src/message/legacy.ts +58 -9
- package/src/message/v0.ts +324 -0
- package/src/message/versioned.ts +36 -0
- package/src/programs/ed25519.ts +2 -2
- package/src/programs/secp256k1.ts +6 -5
- package/src/programs/vote.ts +21 -0
- package/src/publickey.ts +14 -73
- package/src/transaction/constants.ts +2 -0
- package/src/transaction/index.ts +1 -0
- package/src/transaction/legacy.ts +3 -5
- package/src/transaction/versioned.ts +105 -0
- package/src/utils/ed25519.ts +46 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/makeWebsocketUrl.ts +22 -16
- package/src/utils/secp256k1.ts +18 -0
- package/src/validator-info.ts +3 -5
- package/src/utils/__forks__/react-native/url-impl.ts +0 -2
- package/src/utils/url-impl.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/web3.js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.55.0",
|
|
4
4
|
"description": "Solana Javascript API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@babel/runtime": "^7.12.5",
|
|
61
|
-
"@
|
|
61
|
+
"@noble/ed25519": "^1.7.0",
|
|
62
|
+
"@noble/hashes": "^1.1.2",
|
|
63
|
+
"@noble/secp256k1": "^1.6.3",
|
|
62
64
|
"@solana/buffer-layout": "^4.0.0",
|
|
63
65
|
"bigint-buffer": "^1.1.5",
|
|
64
66
|
"bn.js": "^5.0.0",
|
|
@@ -69,11 +71,8 @@
|
|
|
69
71
|
"jayson": "^3.4.4",
|
|
70
72
|
"js-sha3": "^0.8.0",
|
|
71
73
|
"node-fetch": "2",
|
|
72
|
-
"react-native-url-polyfill": "^1.3.0",
|
|
73
74
|
"rpc-websockets": "^7.5.0",
|
|
74
|
-
"
|
|
75
|
-
"superstruct": "^0.14.2",
|
|
76
|
-
"tweetnacl": "^1.0.3"
|
|
75
|
+
"superstruct": "^0.14.2"
|
|
77
76
|
},
|
|
78
77
|
"devDependencies": {
|
|
79
78
|
"@babel/core": "^7.12.13",
|
|
@@ -101,7 +100,6 @@
|
|
|
101
100
|
"@types/mz": "^2.7.3",
|
|
102
101
|
"@types/node": "^17.0.24",
|
|
103
102
|
"@types/node-fetch": "2",
|
|
104
|
-
"@types/secp256k1": "^4.0.1",
|
|
105
103
|
"@types/sinon": "^10.0.0",
|
|
106
104
|
"@types/sinon-chai": "^3.2.8",
|
|
107
105
|
"@typescript-eslint/eslint-plugin": "^4.14.2",
|
package/src/account.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {SignKeyPair as KeyPair} from 'tweetnacl';
|
|
3
|
-
import type {Buffer} from 'buffer';
|
|
1
|
+
import {Buffer} from 'buffer';
|
|
4
2
|
|
|
3
|
+
import {generatePrivateKey, getPublicKey} from './utils/ed25519';
|
|
5
4
|
import {toBuffer} from './utils/to-buffer';
|
|
6
5
|
import {PublicKey} from './publickey';
|
|
7
6
|
|
|
@@ -12,7 +11,9 @@ import {PublicKey} from './publickey';
|
|
|
12
11
|
*/
|
|
13
12
|
export class Account {
|
|
14
13
|
/** @internal */
|
|
15
|
-
|
|
14
|
+
private _publicKey: Buffer;
|
|
15
|
+
/** @internal */
|
|
16
|
+
private _secretKey: Buffer;
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Create a new Account object
|
|
@@ -24,9 +25,15 @@ export class Account {
|
|
|
24
25
|
*/
|
|
25
26
|
constructor(secretKey?: Buffer | Uint8Array | Array<number>) {
|
|
26
27
|
if (secretKey) {
|
|
27
|
-
|
|
28
|
+
const secretKeyBuffer = toBuffer(secretKey);
|
|
29
|
+
if (secretKey.length !== 64) {
|
|
30
|
+
throw new Error('bad secret key size');
|
|
31
|
+
}
|
|
32
|
+
this._publicKey = secretKeyBuffer.slice(32, 64);
|
|
33
|
+
this._secretKey = secretKeyBuffer.slice(0, 32);
|
|
28
34
|
} else {
|
|
29
|
-
this.
|
|
35
|
+
this._secretKey = toBuffer(generatePrivateKey());
|
|
36
|
+
this._publicKey = toBuffer(getPublicKey(this._secretKey));
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
|
@@ -34,13 +41,15 @@ export class Account {
|
|
|
34
41
|
* The public key for this account
|
|
35
42
|
*/
|
|
36
43
|
get publicKey(): PublicKey {
|
|
37
|
-
return new PublicKey(this.
|
|
44
|
+
return new PublicKey(this._publicKey);
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
/**
|
|
41
|
-
* The **unencrypted** secret key for this account
|
|
48
|
+
* The **unencrypted** secret key for this account. The first 32 bytes
|
|
49
|
+
* is the private scalar and the last 32 bytes is the public key.
|
|
50
|
+
* Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
|
|
42
51
|
*/
|
|
43
52
|
get secretKey(): Buffer {
|
|
44
|
-
return
|
|
53
|
+
return Buffer.concat([this._secretKey, this._publicKey], 64);
|
|
45
54
|
}
|
|
46
55
|
}
|
package/src/connection.ts
CHANGED
|
@@ -43,7 +43,6 @@ import {
|
|
|
43
43
|
TransactionExpiredTimeoutError,
|
|
44
44
|
} from './transaction/expiry-custom-errors';
|
|
45
45
|
import {makeWebsocketUrl} from './utils/makeWebsocketUrl';
|
|
46
|
-
import {URL} from './utils/url-impl';
|
|
47
46
|
import type {Blockhash} from './blockhash';
|
|
48
47
|
import type {FeeCalculator} from './fee-calculator';
|
|
49
48
|
import type {TransactionSignature} from './transaction';
|
|
@@ -305,6 +304,14 @@ export type BlockheightBasedTransactionConfirmationStrategy = {
|
|
|
305
304
|
signature: TransactionSignature;
|
|
306
305
|
} & BlockhashWithExpiryBlockHeight;
|
|
307
306
|
|
|
307
|
+
/* @internal */
|
|
308
|
+
function assertEndpointUrl(putativeUrl: string) {
|
|
309
|
+
if (/^https?:/.test(putativeUrl) === false) {
|
|
310
|
+
throw new TypeError('Endpoint URL must start with `http:` or `https:`.');
|
|
311
|
+
}
|
|
312
|
+
return putativeUrl;
|
|
313
|
+
}
|
|
314
|
+
|
|
308
315
|
/** @internal */
|
|
309
316
|
function extractCommitmentFromConfig<TConfig>(
|
|
310
317
|
commitmentOrConfig?: Commitment | ({commitment?: Commitment} & TConfig),
|
|
@@ -1117,7 +1124,6 @@ export type PerfSample = {
|
|
|
1117
1124
|
|
|
1118
1125
|
function createRpcClient(
|
|
1119
1126
|
url: string,
|
|
1120
|
-
useHttps: boolean,
|
|
1121
1127
|
httpHeaders?: HttpHeaders,
|
|
1122
1128
|
customFetch?: FetchFn,
|
|
1123
1129
|
fetchMiddleware?: FetchMiddleware,
|
|
@@ -1126,7 +1132,7 @@ function createRpcClient(
|
|
|
1126
1132
|
const fetch = customFetch ? customFetch : fetchImpl;
|
|
1127
1133
|
let agentManager: AgentManager | undefined;
|
|
1128
1134
|
if (!process.env.BROWSER) {
|
|
1129
|
-
agentManager = new AgentManager(useHttps);
|
|
1135
|
+
agentManager = new AgentManager(url.startsWith('https:') /* useHttps */);
|
|
1130
1136
|
}
|
|
1131
1137
|
|
|
1132
1138
|
let fetchWithMiddleware: FetchFn | undefined;
|
|
@@ -2493,9 +2499,6 @@ export class Connection {
|
|
|
2493
2499
|
endpoint: string,
|
|
2494
2500
|
commitmentOrConfig?: Commitment | ConnectionConfig,
|
|
2495
2501
|
) {
|
|
2496
|
-
let url = new URL(endpoint);
|
|
2497
|
-
const useHttps = url.protocol === 'https:';
|
|
2498
|
-
|
|
2499
2502
|
let wsEndpoint;
|
|
2500
2503
|
let httpHeaders;
|
|
2501
2504
|
let fetch;
|
|
@@ -2514,12 +2517,11 @@ export class Connection {
|
|
|
2514
2517
|
disableRetryOnRateLimit = commitmentOrConfig.disableRetryOnRateLimit;
|
|
2515
2518
|
}
|
|
2516
2519
|
|
|
2517
|
-
this._rpcEndpoint = endpoint;
|
|
2520
|
+
this._rpcEndpoint = assertEndpointUrl(endpoint);
|
|
2518
2521
|
this._rpcWsEndpoint = wsEndpoint || makeWebsocketUrl(endpoint);
|
|
2519
2522
|
|
|
2520
2523
|
this._rpcClient = createRpcClient(
|
|
2521
|
-
|
|
2522
|
-
useHttps,
|
|
2524
|
+
endpoint,
|
|
2523
2525
|
httpHeaders,
|
|
2524
2526
|
fetch,
|
|
2525
2527
|
fetchMiddleware,
|
package/src/keypair.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {generateKeypair, getPublicKey, Ed25519Keypair} from './utils/ed25519';
|
|
3
2
|
import {PublicKey} from './publickey';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -10,14 +9,6 @@ export interface Signer {
|
|
|
10
9
|
secretKey: Uint8Array;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
/**
|
|
14
|
-
* Ed25519 Keypair
|
|
15
|
-
*/
|
|
16
|
-
export interface Ed25519Keypair {
|
|
17
|
-
publicKey: Uint8Array;
|
|
18
|
-
secretKey: Uint8Array;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
12
|
/**
|
|
22
13
|
* An account keypair used for signing transactions.
|
|
23
14
|
*/
|
|
@@ -31,18 +22,14 @@ export class Keypair {
|
|
|
31
22
|
* @param keypair ed25519 keypair
|
|
32
23
|
*/
|
|
33
24
|
constructor(keypair?: Ed25519Keypair) {
|
|
34
|
-
|
|
35
|
-
this._keypair = keypair;
|
|
36
|
-
} else {
|
|
37
|
-
this._keypair = nacl.sign.keyPair();
|
|
38
|
-
}
|
|
25
|
+
this._keypair = keypair ?? generateKeypair();
|
|
39
26
|
}
|
|
40
27
|
|
|
41
28
|
/**
|
|
42
29
|
* Generate a new random keypair
|
|
43
30
|
*/
|
|
44
31
|
static generate(): Keypair {
|
|
45
|
-
return new Keypair(
|
|
32
|
+
return new Keypair(generateKeypair());
|
|
46
33
|
}
|
|
47
34
|
|
|
48
35
|
/**
|
|
@@ -61,16 +48,20 @@ export class Keypair {
|
|
|
61
48
|
secretKey: Uint8Array,
|
|
62
49
|
options?: {skipValidation?: boolean},
|
|
63
50
|
): Keypair {
|
|
64
|
-
|
|
51
|
+
if (secretKey.byteLength !== 64) {
|
|
52
|
+
throw new Error('bad secret key size');
|
|
53
|
+
}
|
|
54
|
+
const publicKey = secretKey.slice(32, 64);
|
|
65
55
|
if (!options || !options.skipValidation) {
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
const privateScalar = secretKey.slice(0, 32);
|
|
57
|
+
const computedPublicKey = getPublicKey(privateScalar);
|
|
58
|
+
for (let ii = 0; ii < 32; ii++) {
|
|
59
|
+
if (publicKey[ii] !== computedPublicKey[ii]) {
|
|
60
|
+
throw new Error('provided secretKey is invalid');
|
|
61
|
+
}
|
|
71
62
|
}
|
|
72
63
|
}
|
|
73
|
-
return new Keypair(
|
|
64
|
+
return new Keypair({publicKey, secretKey});
|
|
74
65
|
}
|
|
75
66
|
|
|
76
67
|
/**
|
|
@@ -79,7 +70,11 @@ export class Keypair {
|
|
|
79
70
|
* @param seed seed byte array
|
|
80
71
|
*/
|
|
81
72
|
static fromSeed(seed: Uint8Array): Keypair {
|
|
82
|
-
|
|
73
|
+
const publicKey = getPublicKey(seed);
|
|
74
|
+
const secretKey = new Uint8Array(64);
|
|
75
|
+
secretKey.set(seed);
|
|
76
|
+
secretKey.set(publicKey, 32);
|
|
77
|
+
return new Keypair({publicKey, secretKey});
|
|
83
78
|
}
|
|
84
79
|
|
|
85
80
|
/**
|
package/src/layout.ts
CHANGED
|
@@ -8,6 +8,13 @@ export const publicKey = (property: string = 'publicKey') => {
|
|
|
8
8
|
return BufferLayout.blob(32, property);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Layout for a signature
|
|
13
|
+
*/
|
|
14
|
+
export const signature = (property: string = 'signature') => {
|
|
15
|
+
return BufferLayout.blob(64, property);
|
|
16
|
+
};
|
|
17
|
+
|
|
11
18
|
/**
|
|
12
19
|
* Layout for a 64bit unsigned value
|
|
13
20
|
*/
|
package/src/message/index.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import {PublicKey} from '../publickey';
|
|
2
|
+
|
|
1
3
|
export * from './legacy';
|
|
4
|
+
export * from './versioned';
|
|
5
|
+
export * from './v0';
|
|
2
6
|
|
|
3
7
|
/**
|
|
4
8
|
* The message header, identifying signed and read-only account
|
|
@@ -15,18 +19,27 @@ export type MessageHeader = {
|
|
|
15
19
|
numReadonlyUnsignedAccounts: number;
|
|
16
20
|
};
|
|
17
21
|
|
|
22
|
+
/**
|
|
23
|
+
* An address table lookup used to load additional accounts
|
|
24
|
+
*/
|
|
25
|
+
export type MessageAddressTableLookup = {
|
|
26
|
+
accountKey: PublicKey;
|
|
27
|
+
writableIndexes: Array<number>;
|
|
28
|
+
readonlyIndexes: Array<number>;
|
|
29
|
+
};
|
|
30
|
+
|
|
18
31
|
/**
|
|
19
32
|
* An instruction to execute by a program
|
|
20
33
|
*
|
|
21
34
|
* @property {number} programIdIndex
|
|
22
|
-
* @property {number[]}
|
|
23
|
-
* @property {
|
|
35
|
+
* @property {number[]} accountKeyIndexes
|
|
36
|
+
* @property {Uint8Array} data
|
|
24
37
|
*/
|
|
25
|
-
export type
|
|
38
|
+
export type MessageCompiledInstruction = {
|
|
26
39
|
/** Index into the transaction keys array indicating the program account that executes this instruction */
|
|
27
40
|
programIdIndex: number;
|
|
28
41
|
/** Ordered indices into the transaction keys array indicating which accounts to pass to the program */
|
|
29
|
-
|
|
30
|
-
/** The program input data
|
|
31
|
-
data:
|
|
42
|
+
accountKeyIndexes: number[];
|
|
43
|
+
/** The program input data */
|
|
44
|
+
data: Uint8Array;
|
|
32
45
|
};
|
package/src/message/legacy.ts
CHANGED
|
@@ -2,13 +2,33 @@ import bs58 from 'bs58';
|
|
|
2
2
|
import {Buffer} from 'buffer';
|
|
3
3
|
import * as BufferLayout from '@solana/buffer-layout';
|
|
4
4
|
|
|
5
|
-
import {PublicKey} from '../publickey';
|
|
5
|
+
import {PublicKey, PUBLIC_KEY_LENGTH} from '../publickey';
|
|
6
6
|
import type {Blockhash} from '../blockhash';
|
|
7
7
|
import * as Layout from '../layout';
|
|
8
|
-
import {PACKET_DATA_SIZE} from '../transaction/constants';
|
|
8
|
+
import {PACKET_DATA_SIZE, VERSION_PREFIX_MASK} from '../transaction/constants';
|
|
9
9
|
import * as shortvec from '../utils/shortvec-encoding';
|
|
10
10
|
import {toBuffer} from '../utils/to-buffer';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
MessageHeader,
|
|
13
|
+
MessageAddressTableLookup,
|
|
14
|
+
MessageCompiledInstruction,
|
|
15
|
+
} from './index';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An instruction to execute by a program
|
|
19
|
+
*
|
|
20
|
+
* @property {number} programIdIndex
|
|
21
|
+
* @property {number[]} accounts
|
|
22
|
+
* @property {string} data
|
|
23
|
+
*/
|
|
24
|
+
export type CompiledInstruction = {
|
|
25
|
+
/** Index into the transaction keys array indicating the program account that executes this instruction */
|
|
26
|
+
programIdIndex: number;
|
|
27
|
+
/** Ordered indices into the transaction keys array indicating which accounts to pass to the program */
|
|
28
|
+
accounts: number[];
|
|
29
|
+
/** The program input data encoded as base 58 */
|
|
30
|
+
data: string;
|
|
31
|
+
};
|
|
12
32
|
|
|
13
33
|
/**
|
|
14
34
|
* Message constructor arguments
|
|
@@ -24,8 +44,6 @@ export type MessageArgs = {
|
|
|
24
44
|
instructions: CompiledInstruction[];
|
|
25
45
|
};
|
|
26
46
|
|
|
27
|
-
const PUBKEY_LENGTH = 32;
|
|
28
|
-
|
|
29
47
|
/**
|
|
30
48
|
* List of instructions to be processed atomically
|
|
31
49
|
*/
|
|
@@ -53,6 +71,28 @@ export class Message {
|
|
|
53
71
|
);
|
|
54
72
|
}
|
|
55
73
|
|
|
74
|
+
get version(): 'legacy' {
|
|
75
|
+
return 'legacy';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get staticAccountKeys(): Array<PublicKey> {
|
|
79
|
+
return this.accountKeys;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get compiledInstructions(): Array<MessageCompiledInstruction> {
|
|
83
|
+
return this.instructions.map(
|
|
84
|
+
(ix): MessageCompiledInstruction => ({
|
|
85
|
+
programIdIndex: ix.programIdIndex,
|
|
86
|
+
accountKeyIndexes: ix.accounts,
|
|
87
|
+
data: bs58.decode(ix.data),
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get addressTableLookups(): Array<MessageAddressTableLookup> {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
isAccountSigner(index: number): boolean {
|
|
57
97
|
return index < this.header.numRequiredSignatures;
|
|
58
98
|
}
|
|
@@ -193,19 +233,28 @@ export class Message {
|
|
|
193
233
|
let byteArray = [...buffer];
|
|
194
234
|
|
|
195
235
|
const numRequiredSignatures = byteArray.shift() as number;
|
|
236
|
+
if (
|
|
237
|
+
numRequiredSignatures !==
|
|
238
|
+
(numRequiredSignatures & VERSION_PREFIX_MASK)
|
|
239
|
+
) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
'Versioned messages must be deserialized with VersionedMessage.deserialize()',
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
196
245
|
const numReadonlySignedAccounts = byteArray.shift() as number;
|
|
197
246
|
const numReadonlyUnsignedAccounts = byteArray.shift() as number;
|
|
198
247
|
|
|
199
248
|
const accountCount = shortvec.decodeLength(byteArray);
|
|
200
249
|
let accountKeys = [];
|
|
201
250
|
for (let i = 0; i < accountCount; i++) {
|
|
202
|
-
const account = byteArray.slice(0,
|
|
203
|
-
byteArray = byteArray.slice(
|
|
251
|
+
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
252
|
+
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
204
253
|
accountKeys.push(bs58.encode(Buffer.from(account)));
|
|
205
254
|
}
|
|
206
255
|
|
|
207
|
-
const recentBlockhash = byteArray.slice(0,
|
|
208
|
-
byteArray = byteArray.slice(
|
|
256
|
+
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
257
|
+
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
209
258
|
|
|
210
259
|
const instructionCount = shortvec.decodeLength(byteArray);
|
|
211
260
|
let instructions: CompiledInstruction[] = [];
|