@solana/web3.js 1.52.0 → 1.54.1
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 +6188 -7481
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +6183 -7482
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +6219 -7531
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +957 -832
- package/lib/index.esm.js +6214 -7532
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +20976 -27402
- 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 +6188 -7480
- package/lib/index.native.js.map +1 -1
- package/package.json +5 -7
- package/src/account-data.ts +39 -0
- package/src/account.ts +19 -10
- package/src/connection.ts +40 -14
- package/src/index.ts +3 -14
- package/src/keypair.ts +19 -24
- package/src/layout.ts +7 -0
- package/src/loader.ts +4 -5
- package/src/message/index.ts +45 -0
- package/src/{message.ts → message/legacy.ts} +46 -27
- package/src/message/v0.ts +324 -0
- package/src/message/versioned.ts +27 -0
- package/src/nonce-account.ts +1 -1
- package/src/{address-lookup-table-program.ts → programs/address-lookup-table/index.ts} +8 -6
- package/src/programs/address-lookup-table/state.ts +84 -0
- package/src/{compute-budget.ts → programs/compute-budget.ts} +4 -4
- package/src/{ed25519-program.ts → programs/ed25519.ts} +6 -6
- package/src/programs/index.ts +7 -0
- package/src/{secp256k1-program.ts → programs/secp256k1.ts} +10 -9
- package/src/{stake-program.ts → programs/stake.ts} +7 -7
- package/src/{system-program.ts → programs/system.ts} +8 -8
- package/src/{vote-program.ts → programs/vote.ts} +28 -7
- package/src/publickey.ts +16 -75
- package/src/{transaction-constants.ts → transaction/constants.ts} +2 -0
- package/src/{util/tx-expiry-custom-errors.ts → transaction/expiry-custom-errors.ts} +0 -0
- package/src/transaction/index.ts +4 -0
- package/src/{transaction.ts → transaction/legacy.ts} +13 -18
- package/src/transaction/versioned.ts +105 -0
- package/src/{util → utils}/assert.ts +0 -0
- package/src/{util → utils}/bigint.ts +0 -0
- package/src/{util → utils}/borsh-schema.ts +0 -0
- package/src/{util → utils}/cluster.ts +0 -0
- package/src/utils/ed25519.ts +46 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/makeWebsocketUrl.ts +26 -0
- package/src/{util → utils}/promise-timeout.ts +0 -0
- package/src/utils/secp256k1.ts +18 -0
- package/src/{util → utils}/send-and-confirm-raw-transaction.ts +0 -0
- package/src/{util → utils}/send-and-confirm-transaction.ts +0 -0
- package/src/{util → utils}/shortvec-encoding.ts +0 -0
- package/src/{util → utils}/sleep.ts +0 -0
- package/src/{util → utils}/to-buffer.ts +0 -0
- package/src/validator-info.ts +4 -6
- package/src/vote-account.ts +1 -1
- package/src/util/__forks__/react-native/url-impl.ts +0 -2
- package/src/util/makeWebsocketUrl.ts +0 -20
- package/src/util/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.54.1",
|
|
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",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as BufferLayout from '@solana/buffer-layout';
|
|
2
|
+
|
|
3
|
+
export interface IAccountStateData {
|
|
4
|
+
readonly typeIndex: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export type AccountType<TInputData extends IAccountStateData> = {
|
|
11
|
+
/** The account type index (from solana upstream program) */
|
|
12
|
+
index: number;
|
|
13
|
+
/** The BufferLayout to use to build data */
|
|
14
|
+
layout: BufferLayout.Layout<TInputData>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Decode account data buffer using an AccountType
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export function decodeData<TAccountStateData extends IAccountStateData>(
|
|
22
|
+
type: AccountType<TAccountStateData>,
|
|
23
|
+
data: Uint8Array,
|
|
24
|
+
): TAccountStateData {
|
|
25
|
+
let decoded: TAccountStateData;
|
|
26
|
+
try {
|
|
27
|
+
decoded = type.layout.decode(data);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
throw new Error('invalid instruction; ' + err);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (decoded.typeIndex !== type.index) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`invalid account data; account type mismatch ${decoded.typeIndex} != ${type.index}`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return decoded;
|
|
39
|
+
}
|
package/src/account.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {SignKeyPair as KeyPair} from 'tweetnacl';
|
|
3
|
-
import type {Buffer} from 'buffer';
|
|
1
|
+
import {Buffer} from 'buffer';
|
|
4
2
|
|
|
5
|
-
import {
|
|
3
|
+
import {generatePrivateKey, getPublicKey} from './utils/ed25519';
|
|
4
|
+
import {toBuffer} from './utils/to-buffer';
|
|
6
5
|
import {PublicKey} from './publickey';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -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
|
@@ -24,7 +24,6 @@ import type {Struct} from 'superstruct';
|
|
|
24
24
|
import {Client as RpcWebSocketClient} from 'rpc-websockets';
|
|
25
25
|
import RpcClient from 'jayson/lib/client/browser';
|
|
26
26
|
|
|
27
|
-
import {URL} from './util/url-impl';
|
|
28
27
|
import {AgentManager} from './agent-manager';
|
|
29
28
|
import {EpochSchedule} from './epoch-schedule';
|
|
30
29
|
import {SendTransactionError, SolanaJSONRPCError} from './errors';
|
|
@@ -35,14 +34,15 @@ import {Signer} from './keypair';
|
|
|
35
34
|
import {MS_PER_SLOT} from './timing';
|
|
36
35
|
import {Transaction, TransactionStatus} from './transaction';
|
|
37
36
|
import {Message} from './message';
|
|
38
|
-
import
|
|
39
|
-
import
|
|
40
|
-
import {
|
|
37
|
+
import {AddressLookupTableAccount} from './programs/address-lookup-table/state';
|
|
38
|
+
import assert from './utils/assert';
|
|
39
|
+
import {sleep} from './utils/sleep';
|
|
40
|
+
import {toBuffer} from './utils/to-buffer';
|
|
41
41
|
import {
|
|
42
42
|
TransactionExpiredBlockheightExceededError,
|
|
43
43
|
TransactionExpiredTimeoutError,
|
|
44
|
-
} from './
|
|
45
|
-
import {makeWebsocketUrl} from './
|
|
44
|
+
} from './transaction/expiry-custom-errors';
|
|
45
|
+
import {makeWebsocketUrl} from './utils/makeWebsocketUrl';
|
|
46
46
|
import type {Blockhash} from './blockhash';
|
|
47
47
|
import type {FeeCalculator} from './fee-calculator';
|
|
48
48
|
import type {TransactionSignature} from './transaction';
|
|
@@ -304,6 +304,14 @@ export type BlockheightBasedTransactionConfirmationStrategy = {
|
|
|
304
304
|
signature: TransactionSignature;
|
|
305
305
|
} & BlockhashWithExpiryBlockHeight;
|
|
306
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
|
+
|
|
307
315
|
/** @internal */
|
|
308
316
|
function extractCommitmentFromConfig<TConfig>(
|
|
309
317
|
commitmentOrConfig?: Commitment | ({commitment?: Commitment} & TConfig),
|
|
@@ -1116,7 +1124,6 @@ export type PerfSample = {
|
|
|
1116
1124
|
|
|
1117
1125
|
function createRpcClient(
|
|
1118
1126
|
url: string,
|
|
1119
|
-
useHttps: boolean,
|
|
1120
1127
|
httpHeaders?: HttpHeaders,
|
|
1121
1128
|
customFetch?: FetchFn,
|
|
1122
1129
|
fetchMiddleware?: FetchMiddleware,
|
|
@@ -1125,7 +1132,7 @@ function createRpcClient(
|
|
|
1125
1132
|
const fetch = customFetch ? customFetch : fetchImpl;
|
|
1126
1133
|
let agentManager: AgentManager | undefined;
|
|
1127
1134
|
if (!process.env.BROWSER) {
|
|
1128
|
-
agentManager = new AgentManager(useHttps);
|
|
1135
|
+
agentManager = new AgentManager(url.startsWith('https:') /* useHttps */);
|
|
1129
1136
|
}
|
|
1130
1137
|
|
|
1131
1138
|
let fetchWithMiddleware: FetchFn | undefined;
|
|
@@ -2492,9 +2499,6 @@ export class Connection {
|
|
|
2492
2499
|
endpoint: string,
|
|
2493
2500
|
commitmentOrConfig?: Commitment | ConnectionConfig,
|
|
2494
2501
|
) {
|
|
2495
|
-
let url = new URL(endpoint);
|
|
2496
|
-
const useHttps = url.protocol === 'https:';
|
|
2497
|
-
|
|
2498
2502
|
let wsEndpoint;
|
|
2499
2503
|
let httpHeaders;
|
|
2500
2504
|
let fetch;
|
|
@@ -2513,12 +2517,11 @@ export class Connection {
|
|
|
2513
2517
|
disableRetryOnRateLimit = commitmentOrConfig.disableRetryOnRateLimit;
|
|
2514
2518
|
}
|
|
2515
2519
|
|
|
2516
|
-
this._rpcEndpoint = endpoint;
|
|
2520
|
+
this._rpcEndpoint = assertEndpointUrl(endpoint);
|
|
2517
2521
|
this._rpcWsEndpoint = wsEndpoint || makeWebsocketUrl(endpoint);
|
|
2518
2522
|
|
|
2519
2523
|
this._rpcClient = createRpcClient(
|
|
2520
|
-
|
|
2521
|
-
useHttps,
|
|
2524
|
+
endpoint,
|
|
2522
2525
|
httpHeaders,
|
|
2523
2526
|
fetch,
|
|
2524
2527
|
fetchMiddleware,
|
|
@@ -4218,6 +4221,29 @@ export class Connection {
|
|
|
4218
4221
|
return res.result;
|
|
4219
4222
|
}
|
|
4220
4223
|
|
|
4224
|
+
async getAddressLookupTable(
|
|
4225
|
+
accountKey: PublicKey,
|
|
4226
|
+
config?: GetAccountInfoConfig,
|
|
4227
|
+
): Promise<RpcResponseAndContext<AddressLookupTableAccount | null>> {
|
|
4228
|
+
const {context, value: accountInfo} = await this.getAccountInfoAndContext(
|
|
4229
|
+
accountKey,
|
|
4230
|
+
config,
|
|
4231
|
+
);
|
|
4232
|
+
|
|
4233
|
+
let value = null;
|
|
4234
|
+
if (accountInfo !== null) {
|
|
4235
|
+
value = new AddressLookupTableAccount({
|
|
4236
|
+
key: accountKey,
|
|
4237
|
+
state: AddressLookupTableAccount.deserialize(accountInfo.data),
|
|
4238
|
+
});
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
return {
|
|
4242
|
+
context,
|
|
4243
|
+
value,
|
|
4244
|
+
};
|
|
4245
|
+
}
|
|
4246
|
+
|
|
4221
4247
|
/**
|
|
4222
4248
|
* Fetch the contents of a Nonce account from the cluster, return with context
|
|
4223
4249
|
*/
|
package/src/index.ts
CHANGED
|
@@ -1,33 +1,22 @@
|
|
|
1
1
|
export * from './account';
|
|
2
|
-
export * from './address-lookup-table-program';
|
|
3
2
|
export * from './blockhash';
|
|
4
3
|
export * from './bpf-loader-deprecated';
|
|
5
4
|
export * from './bpf-loader';
|
|
6
|
-
export * from './compute-budget';
|
|
7
5
|
export * from './connection';
|
|
8
6
|
export * from './epoch-schedule';
|
|
9
|
-
export * from './
|
|
7
|
+
export * from './errors';
|
|
10
8
|
export * from './fee-calculator';
|
|
11
9
|
export * from './keypair';
|
|
12
10
|
export * from './loader';
|
|
13
11
|
export * from './message';
|
|
14
12
|
export * from './nonce-account';
|
|
13
|
+
export * from './programs';
|
|
15
14
|
export * from './publickey';
|
|
16
|
-
export * from './stake-program';
|
|
17
|
-
export * from './system-program';
|
|
18
|
-
export * from './secp256k1-program';
|
|
19
15
|
export * from './transaction';
|
|
20
|
-
export * from './transaction-constants';
|
|
21
16
|
export * from './validator-info';
|
|
22
17
|
export * from './vote-account';
|
|
23
|
-
export * from './vote-program';
|
|
24
18
|
export * from './sysvar';
|
|
25
|
-
export * from './
|
|
26
|
-
export * from './util/borsh-schema';
|
|
27
|
-
export * from './util/send-and-confirm-transaction';
|
|
28
|
-
export * from './util/send-and-confirm-raw-transaction';
|
|
29
|
-
export * from './util/tx-expiry-custom-errors';
|
|
30
|
-
export * from './util/cluster';
|
|
19
|
+
export * from './utils';
|
|
31
20
|
|
|
32
21
|
/**
|
|
33
22
|
* There are 1-billion lamports in one SOL
|
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/loader.ts
CHANGED
|
@@ -2,15 +2,14 @@ import {Buffer} from 'buffer';
|
|
|
2
2
|
import * as BufferLayout from '@solana/buffer-layout';
|
|
3
3
|
|
|
4
4
|
import {PublicKey} from './publickey';
|
|
5
|
-
import {Transaction} from './transaction';
|
|
5
|
+
import {Transaction, PACKET_DATA_SIZE} from './transaction';
|
|
6
6
|
import {SYSVAR_RENT_PUBKEY} from './sysvar';
|
|
7
|
-
import {sendAndConfirmTransaction} from './
|
|
8
|
-
import {sleep} from './
|
|
7
|
+
import {sendAndConfirmTransaction} from './utils/send-and-confirm-transaction';
|
|
8
|
+
import {sleep} from './utils/sleep';
|
|
9
9
|
import type {Connection} from './connection';
|
|
10
10
|
import type {Signer} from './keypair';
|
|
11
|
-
import {SystemProgram} from './system
|
|
11
|
+
import {SystemProgram} from './programs/system';
|
|
12
12
|
import {IInstructionInputData} from './instruction';
|
|
13
|
-
import {PACKET_DATA_SIZE} from './transaction-constants';
|
|
14
13
|
|
|
15
14
|
// Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
|
|
16
15
|
// rest of the Transaction fields
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {PublicKey} from '../publickey';
|
|
2
|
+
|
|
3
|
+
export * from './legacy';
|
|
4
|
+
export * from './versioned';
|
|
5
|
+
export * from './v0';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The message header, identifying signed and read-only account
|
|
9
|
+
*/
|
|
10
|
+
export type MessageHeader = {
|
|
11
|
+
/**
|
|
12
|
+
* The number of signatures required for this message to be considered valid. The
|
|
13
|
+
* signatures must match the first `numRequiredSignatures` of `accountKeys`.
|
|
14
|
+
*/
|
|
15
|
+
numRequiredSignatures: number;
|
|
16
|
+
/** The last `numReadonlySignedAccounts` of the signed keys are read-only accounts */
|
|
17
|
+
numReadonlySignedAccounts: number;
|
|
18
|
+
/** The last `numReadonlySignedAccounts` of the unsigned keys are read-only accounts */
|
|
19
|
+
numReadonlyUnsignedAccounts: number;
|
|
20
|
+
};
|
|
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
|
+
|
|
31
|
+
/**
|
|
32
|
+
* An instruction to execute by a program
|
|
33
|
+
*
|
|
34
|
+
* @property {number} programIdIndex
|
|
35
|
+
* @property {number[]} accountKeyIndexes
|
|
36
|
+
* @property {Uint8Array} data
|
|
37
|
+
*/
|
|
38
|
+
export type MessageCompiledInstruction = {
|
|
39
|
+
/** Index into the transaction keys array indicating the program account that executes this instruction */
|
|
40
|
+
programIdIndex: number;
|
|
41
|
+
/** Ordered indices into the transaction keys array indicating which accounts to pass to the program */
|
|
42
|
+
accountKeyIndexes: number[];
|
|
43
|
+
/** The program input data */
|
|
44
|
+
data: Uint8Array;
|
|
45
|
+
};
|
|
@@ -2,27 +2,17 @@ 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 '
|
|
6
|
-
import type {Blockhash} from '
|
|
7
|
-
import * as Layout from '
|
|
8
|
-
import {PACKET_DATA_SIZE} from '
|
|
9
|
-
import * as shortvec from '
|
|
10
|
-
import {toBuffer} from '
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The number of signatures required for this message to be considered valid. The
|
|
18
|
-
* signatures must match the first `numRequiredSignatures` of `accountKeys`.
|
|
19
|
-
*/
|
|
20
|
-
numRequiredSignatures: number;
|
|
21
|
-
/** The last `numReadonlySignedAccounts` of the signed keys are read-only accounts */
|
|
22
|
-
numReadonlySignedAccounts: number;
|
|
23
|
-
/** The last `numReadonlySignedAccounts` of the unsigned keys are read-only accounts */
|
|
24
|
-
numReadonlyUnsignedAccounts: number;
|
|
25
|
-
};
|
|
5
|
+
import {PublicKey, PUBLIC_KEY_LENGTH} from '../publickey';
|
|
6
|
+
import type {Blockhash} from '../blockhash';
|
|
7
|
+
import * as Layout from '../layout';
|
|
8
|
+
import {PACKET_DATA_SIZE, VERSION_PREFIX_MASK} from '../transaction/constants';
|
|
9
|
+
import * as shortvec from '../utils/shortvec-encoding';
|
|
10
|
+
import {toBuffer} from '../utils/to-buffer';
|
|
11
|
+
import {
|
|
12
|
+
MessageHeader,
|
|
13
|
+
MessageAddressTableLookup,
|
|
14
|
+
MessageCompiledInstruction,
|
|
15
|
+
} from './index';
|
|
26
16
|
|
|
27
17
|
/**
|
|
28
18
|
* An instruction to execute by a program
|
|
@@ -54,8 +44,6 @@ export type MessageArgs = {
|
|
|
54
44
|
instructions: CompiledInstruction[];
|
|
55
45
|
};
|
|
56
46
|
|
|
57
|
-
const PUBKEY_LENGTH = 32;
|
|
58
|
-
|
|
59
47
|
/**
|
|
60
48
|
* List of instructions to be processed atomically
|
|
61
49
|
*/
|
|
@@ -83,6 +71,28 @@ export class Message {
|
|
|
83
71
|
);
|
|
84
72
|
}
|
|
85
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
|
+
|
|
86
96
|
isAccountSigner(index: number): boolean {
|
|
87
97
|
return index < this.header.numRequiredSignatures;
|
|
88
98
|
}
|
|
@@ -223,19 +233,28 @@ export class Message {
|
|
|
223
233
|
let byteArray = [...buffer];
|
|
224
234
|
|
|
225
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
|
+
|
|
226
245
|
const numReadonlySignedAccounts = byteArray.shift() as number;
|
|
227
246
|
const numReadonlyUnsignedAccounts = byteArray.shift() as number;
|
|
228
247
|
|
|
229
248
|
const accountCount = shortvec.decodeLength(byteArray);
|
|
230
249
|
let accountKeys = [];
|
|
231
250
|
for (let i = 0; i < accountCount; i++) {
|
|
232
|
-
const account = byteArray.slice(0,
|
|
233
|
-
byteArray = byteArray.slice(
|
|
251
|
+
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
252
|
+
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
234
253
|
accountKeys.push(bs58.encode(Buffer.from(account)));
|
|
235
254
|
}
|
|
236
255
|
|
|
237
|
-
const recentBlockhash = byteArray.slice(0,
|
|
238
|
-
byteArray = byteArray.slice(
|
|
256
|
+
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
257
|
+
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
239
258
|
|
|
240
259
|
const instructionCount = shortvec.decodeLength(byteArray);
|
|
241
260
|
let instructions: CompiledInstruction[] = [];
|