@solana/web3.js 1.36.0 → 1.37.2
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 +9848 -0
- package/lib/index.browser.cjs.js.map +1 -0
- package/lib/index.browser.esm.js +168 -52
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +169 -51
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +52 -13
- package/lib/index.esm.js +169 -51
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +1593 -1238
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +5 -4
- package/lib/index.iife.min.js.map +1 -1
- package/module.flow.js +83 -14
- package/package.json +5 -4
- package/src/connection.ts +106 -8
- package/src/ed25519-program.ts +21 -4
- package/src/instruction.ts +15 -5
- package/src/layout.ts +59 -19
- package/src/loader.ts +16 -3
- package/src/message.ts +21 -4
- package/src/nonce-account.ts +15 -2
- package/src/secp256k1-program.ts +15 -1
- package/src/stake-program.ts +83 -21
- package/src/system-program.ts +100 -36
- package/src/transaction.ts +8 -0
- package/src/vote-account.ts +55 -27
- package/src/vote-program.ts +37 -10
package/module.flow.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Flowtype definitions for index
|
|
3
3
|
* Generated by Flowgen from a Typescript Definition
|
|
4
|
-
* Flowgen v1.
|
|
4
|
+
* Flowgen v1.17.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
declare module "@solana/web3.js" {
|
|
@@ -570,6 +570,11 @@ declare module "@solana/web3.js" {
|
|
|
570
570
|
*/
|
|
571
571
|
serializeMessage(): Buffer;
|
|
572
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Get the estimated fee associated with a transaction
|
|
575
|
+
*/
|
|
576
|
+
getEstimatedFee(connection: Connection): Promise<number>;
|
|
577
|
+
|
|
573
578
|
/**
|
|
574
579
|
* Specify the public keys which will be used to sign the Transaction.
|
|
575
580
|
* The first signer will be used as the transaction fee payer account.
|
|
@@ -1498,6 +1503,61 @@ declare module "@solana/web3.js" {
|
|
|
1498
1503
|
...
|
|
1499
1504
|
};
|
|
1500
1505
|
|
|
1506
|
+
/**
|
|
1507
|
+
* recent block production information
|
|
1508
|
+
*/
|
|
1509
|
+
declare export type BlockProduction = $ReadOnly<{
|
|
1510
|
+
/**
|
|
1511
|
+
* a dictionary of validator identities, as base-58 encoded strings. Value is a two element array containing the number of leader slots and the number of blocks produced
|
|
1512
|
+
*/
|
|
1513
|
+
byIdentity: $ReadOnly<{ [key: string]: $ReadOnlyArray<number>, ... }>,
|
|
1514
|
+
|
|
1515
|
+
/**
|
|
1516
|
+
* Block production slot range
|
|
1517
|
+
*/
|
|
1518
|
+
range: $ReadOnly<{
|
|
1519
|
+
/**
|
|
1520
|
+
* first slot of the block production information (inclusive)
|
|
1521
|
+
*/
|
|
1522
|
+
firstSlot: number,
|
|
1523
|
+
|
|
1524
|
+
/**
|
|
1525
|
+
* last slot of block production information (inclusive)
|
|
1526
|
+
*/
|
|
1527
|
+
lastSlot: number,
|
|
1528
|
+
...
|
|
1529
|
+
}>,
|
|
1530
|
+
...
|
|
1531
|
+
}>;
|
|
1532
|
+
declare export type GetBlockProductionConfig = {
|
|
1533
|
+
/**
|
|
1534
|
+
* Optional commitment level
|
|
1535
|
+
*/
|
|
1536
|
+
commitment?: Commitment,
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* Slot range to return block production for. If parameter not provided, defaults to current epoch.
|
|
1540
|
+
*/
|
|
1541
|
+
range?: {
|
|
1542
|
+
/**
|
|
1543
|
+
* first slot to return block production information for (inclusive)
|
|
1544
|
+
*/
|
|
1545
|
+
firstSlot: number,
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* last slot to return block production information for (inclusive). If parameter not provided, defaults to the highest slot
|
|
1549
|
+
*/
|
|
1550
|
+
lastSlot?: number,
|
|
1551
|
+
...
|
|
1552
|
+
},
|
|
1553
|
+
|
|
1554
|
+
/**
|
|
1555
|
+
* Only return results for this validator identity (base-58 encoded)
|
|
1556
|
+
*/
|
|
1557
|
+
identity?: string,
|
|
1558
|
+
...
|
|
1559
|
+
};
|
|
1560
|
+
|
|
1501
1561
|
/**
|
|
1502
1562
|
* A performance sample
|
|
1503
1563
|
*/
|
|
@@ -2115,7 +2175,7 @@ declare module "@solana/web3.js" {
|
|
|
2115
2175
|
fetchMiddleware?: FetchMiddleware,
|
|
2116
2176
|
|
|
2117
2177
|
/**
|
|
2118
|
-
* Optional Disable
|
|
2178
|
+
* Optional Disable retrying calls when server responds with HTTP 429 (Too Many Requests)
|
|
2119
2179
|
*/
|
|
2120
2180
|
disableRetryOnRateLimit?: boolean,
|
|
2121
2181
|
|
|
@@ -2145,6 +2205,11 @@ declare module "@solana/web3.js" {
|
|
|
2145
2205
|
*/
|
|
2146
2206
|
commitment: Commitment | void;
|
|
2147
2207
|
|
|
2208
|
+
/**
|
|
2209
|
+
* The RPC endpoint
|
|
2210
|
+
*/
|
|
2211
|
+
rpcEndpoint: string;
|
|
2212
|
+
|
|
2148
2213
|
/**
|
|
2149
2214
|
* Fetch the balance for the specified public key, return with context
|
|
2150
2215
|
*/
|
|
@@ -2544,6 +2609,10 @@ lastValidBlockHeight: number,...
|
|
|
2544
2609
|
...
|
|
2545
2610
|
}
|
|
2546
2611
|
): Promise<BlockResponse | null>;
|
|
2612
|
+
getBlockHeight(commitment?: Commitment): Promise<number>;
|
|
2613
|
+
getBlockProduction(
|
|
2614
|
+
configOrCommitment?: GetBlockProductionConfig | Commitment
|
|
2615
|
+
): Promise<RpcResponseAndContext<BlockProduction>>;
|
|
2547
2616
|
|
|
2548
2617
|
/**
|
|
2549
2618
|
* Fetch a confirmed or finalized transaction from the cluster.
|
|
@@ -3266,14 +3335,14 @@ lastValidBlockHeight: number,...
|
|
|
3266
3335
|
* An enumeration of valid StakeInstructionType's
|
|
3267
3336
|
*/
|
|
3268
3337
|
declare export type StakeInstructionType =
|
|
3269
|
-
| "AuthorizeWithSeed"
|
|
3270
3338
|
| "Authorize"
|
|
3339
|
+
| "AuthorizeWithSeed"
|
|
3271
3340
|
| "Deactivate"
|
|
3272
3341
|
| "Delegate"
|
|
3273
3342
|
| "Initialize"
|
|
3343
|
+
| "Merge"
|
|
3274
3344
|
| "Split"
|
|
3275
|
-
| "Withdraw"
|
|
3276
|
-
| "Merge";
|
|
3345
|
+
| "Withdraw";
|
|
3277
3346
|
|
|
3278
3347
|
/**
|
|
3279
3348
|
* Stake authorization type
|
|
@@ -4063,28 +4132,28 @@ lastValidBlockHeight: number,...
|
|
|
4063
4132
|
/**
|
|
4064
4133
|
* History of how many credits earned by the end of each epoch
|
|
4065
4134
|
*/
|
|
4066
|
-
declare export type EpochCredits = {
|
|
4135
|
+
declare export type EpochCredits = $ReadOnly<{
|
|
4067
4136
|
epoch: number,
|
|
4068
4137
|
credits: number,
|
|
4069
4138
|
prevCredits: number,
|
|
4070
4139
|
...
|
|
4071
|
-
}
|
|
4072
|
-
declare export type AuthorizedVoter = {
|
|
4140
|
+
}>;
|
|
4141
|
+
declare export type AuthorizedVoter = $ReadOnly<{
|
|
4073
4142
|
epoch: number,
|
|
4074
4143
|
authorizedVoter: PublicKey,
|
|
4075
4144
|
...
|
|
4076
|
-
}
|
|
4077
|
-
declare export type PriorVoter = {
|
|
4145
|
+
}>;
|
|
4146
|
+
declare export type PriorVoter = $ReadOnly<{
|
|
4078
4147
|
authorizedPubkey: PublicKey,
|
|
4079
4148
|
epochOfLastAuthorizedSwitch: number,
|
|
4080
4149
|
targetEpoch: number,
|
|
4081
4150
|
...
|
|
4082
|
-
}
|
|
4083
|
-
declare export type BlockTimestamp = {
|
|
4151
|
+
}>;
|
|
4152
|
+
declare export type BlockTimestamp = $ReadOnly<{
|
|
4084
4153
|
slot: number,
|
|
4085
|
-
|
|
4154
|
+
timestamp: number,
|
|
4086
4155
|
...
|
|
4087
|
-
}
|
|
4156
|
+
}>;
|
|
4088
4157
|
|
|
4089
4158
|
/**
|
|
4090
4159
|
* VoteAccount class
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/web3.js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.2",
|
|
4
4
|
"description": "Solana Javascript API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"type:gen": "./scripts/typegen.sh",
|
|
49
49
|
"lint": "set -ex; npm run pretty; eslint . --ext .js,.ts",
|
|
50
50
|
"lint:fix": "npm run pretty:fix && eslint . --fix --ext .js,.ts",
|
|
51
|
-
"
|
|
51
|
+
"type:check": "tsc -p tsconfig.json --noEmit",
|
|
52
|
+
"ok": "run-s lint test doc type:check",
|
|
52
53
|
"pretty": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
|
|
53
54
|
"pretty:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
|
|
54
55
|
"re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
|
|
@@ -60,9 +61,9 @@
|
|
|
60
61
|
"dependencies": {
|
|
61
62
|
"@babel/runtime": "^7.12.5",
|
|
62
63
|
"@ethersproject/sha2": "^5.5.0",
|
|
63
|
-
"@solana/buffer-layout": "^
|
|
64
|
+
"@solana/buffer-layout": "^4.0.0",
|
|
64
65
|
"bn.js": "^5.0.0",
|
|
65
|
-
"borsh": "^0.
|
|
66
|
+
"borsh": "^0.7.0",
|
|
66
67
|
"bs58": "^4.0.1",
|
|
67
68
|
"buffer": "6.0.1",
|
|
68
69
|
"cross-fetch": "^3.1.4",
|
package/src/connection.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import bs58 from 'bs58';
|
|
2
2
|
import {Buffer} from 'buffer';
|
|
3
3
|
import fetch from 'cross-fetch';
|
|
4
|
-
import type {Response} from 'cross-fetch';
|
|
5
4
|
import {
|
|
6
5
|
type as pick,
|
|
7
6
|
number,
|
|
@@ -755,6 +754,48 @@ export type BlockSignatures = {
|
|
|
755
754
|
blockTime: number | null;
|
|
756
755
|
};
|
|
757
756
|
|
|
757
|
+
/**
|
|
758
|
+
* recent block production information
|
|
759
|
+
*/
|
|
760
|
+
export type BlockProduction = Readonly<{
|
|
761
|
+
/** a dictionary of validator identities, as base-58 encoded strings. Value is a two element array containing the number of leader slots and the number of blocks produced */
|
|
762
|
+
byIdentity: Readonly<Record<string, ReadonlyArray<number>>>;
|
|
763
|
+
/** Block production slot range */
|
|
764
|
+
range: Readonly<{
|
|
765
|
+
/** first slot of the block production information (inclusive) */
|
|
766
|
+
firstSlot: number;
|
|
767
|
+
/** last slot of block production information (inclusive) */
|
|
768
|
+
lastSlot: number;
|
|
769
|
+
}>;
|
|
770
|
+
}>;
|
|
771
|
+
|
|
772
|
+
export type GetBlockProductionConfig = {
|
|
773
|
+
/** Optional commitment level */
|
|
774
|
+
commitment?: Commitment;
|
|
775
|
+
/** Slot range to return block production for. If parameter not provided, defaults to current epoch. */
|
|
776
|
+
range?: {
|
|
777
|
+
/** first slot to return block production information for (inclusive) */
|
|
778
|
+
firstSlot: number;
|
|
779
|
+
/** last slot to return block production information for (inclusive). If parameter not provided, defaults to the highest slot */
|
|
780
|
+
lastSlot?: number;
|
|
781
|
+
};
|
|
782
|
+
/** Only return results for this validator identity (base-58 encoded) */
|
|
783
|
+
identity?: string;
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Expected JSON RPC response for the "getBlockProduction" message
|
|
788
|
+
*/
|
|
789
|
+
const BlockProductionResponseStruct = jsonRpcResultAndContext(
|
|
790
|
+
pick({
|
|
791
|
+
byIdentity: record(string(), array(number())),
|
|
792
|
+
range: pick({
|
|
793
|
+
firstSlot: number(),
|
|
794
|
+
lastSlot: number(),
|
|
795
|
+
}),
|
|
796
|
+
}),
|
|
797
|
+
);
|
|
798
|
+
|
|
758
799
|
/**
|
|
759
800
|
* A performance sample
|
|
760
801
|
*/
|
|
@@ -2069,7 +2110,7 @@ export type ConnectionConfig = {
|
|
|
2069
2110
|
httpHeaders?: HttpHeaders;
|
|
2070
2111
|
/** Optional fetch middleware callback */
|
|
2071
2112
|
fetchMiddleware?: FetchMiddleware;
|
|
2072
|
-
/** Optional Disable
|
|
2113
|
+
/** Optional Disable retrying calls when server responds with HTTP 429 (Too Many Requests) */
|
|
2073
2114
|
disableRetryOnRateLimit?: boolean;
|
|
2074
2115
|
/** time to allow for the server to initially process a transaction (in milliseconds) */
|
|
2075
2116
|
confirmTransactionInitialTimeout?: number;
|
|
@@ -2230,6 +2271,13 @@ export class Connection {
|
|
|
2230
2271
|
return this._commitment;
|
|
2231
2272
|
}
|
|
2232
2273
|
|
|
2274
|
+
/**
|
|
2275
|
+
* The RPC endpoint
|
|
2276
|
+
*/
|
|
2277
|
+
get rpcEndpoint(): string {
|
|
2278
|
+
return this._rpcEndpoint;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2233
2281
|
/**
|
|
2234
2282
|
* Fetch the balance for the specified public key, return with context
|
|
2235
2283
|
*/
|
|
@@ -3224,6 +3272,51 @@ export class Connection {
|
|
|
3224
3272
|
};
|
|
3225
3273
|
}
|
|
3226
3274
|
|
|
3275
|
+
/*
|
|
3276
|
+
* Returns the current block height of the node
|
|
3277
|
+
*/
|
|
3278
|
+
async getBlockHeight(commitment?: Commitment): Promise<number> {
|
|
3279
|
+
const args = this._buildArgs([], commitment);
|
|
3280
|
+
const unsafeRes = await this._rpcRequest('getBlockHeight', args);
|
|
3281
|
+
const res = create(unsafeRes, jsonRpcResult(number()));
|
|
3282
|
+
if ('error' in res) {
|
|
3283
|
+
throw new Error(
|
|
3284
|
+
'failed to get block height information: ' + res.error.message,
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
return res.result;
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
/*
|
|
3292
|
+
* Returns recent block production information from the current or previous epoch
|
|
3293
|
+
*/
|
|
3294
|
+
async getBlockProduction(
|
|
3295
|
+
configOrCommitment?: GetBlockProductionConfig | Commitment,
|
|
3296
|
+
): Promise<RpcResponseAndContext<BlockProduction>> {
|
|
3297
|
+
let extra: Omit<GetBlockProductionConfig, 'commitment'> | undefined;
|
|
3298
|
+
let commitment: Commitment | undefined;
|
|
3299
|
+
|
|
3300
|
+
if (typeof configOrCommitment === 'string') {
|
|
3301
|
+
commitment = configOrCommitment;
|
|
3302
|
+
} else if (configOrCommitment) {
|
|
3303
|
+
const {commitment: c, ...rest} = configOrCommitment;
|
|
3304
|
+
commitment = c;
|
|
3305
|
+
extra = rest;
|
|
3306
|
+
}
|
|
3307
|
+
|
|
3308
|
+
const args = this._buildArgs([], commitment, 'base64', extra);
|
|
3309
|
+
const unsafeRes = await this._rpcRequest('getBlockProduction', args);
|
|
3310
|
+
const res = create(unsafeRes, BlockProductionResponseStruct);
|
|
3311
|
+
if ('error' in res) {
|
|
3312
|
+
throw new Error(
|
|
3313
|
+
'failed to get block production information: ' + res.error.message,
|
|
3314
|
+
);
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3317
|
+
return res.result;
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3227
3320
|
/**
|
|
3228
3321
|
* Fetch a confirmed or finalized transaction from the cluster.
|
|
3229
3322
|
*/
|
|
@@ -3785,7 +3878,14 @@ export class Connection {
|
|
|
3785
3878
|
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
|
|
3786
3879
|
let transaction;
|
|
3787
3880
|
if (transactionOrMessage instanceof Transaction) {
|
|
3788
|
-
|
|
3881
|
+
let originalTx: Transaction = transactionOrMessage;
|
|
3882
|
+
transaction = new Transaction({
|
|
3883
|
+
recentBlockhash: originalTx.recentBlockhash,
|
|
3884
|
+
nonceInfo: originalTx.nonceInfo,
|
|
3885
|
+
feePayer: originalTx.feePayer,
|
|
3886
|
+
signatures: [...originalTx.signatures],
|
|
3887
|
+
});
|
|
3888
|
+
transaction.instructions = transactionOrMessage.instructions;
|
|
3789
3889
|
} else {
|
|
3790
3890
|
transaction = Transaction.populate(transactionOrMessage);
|
|
3791
3891
|
}
|
|
@@ -3955,11 +4055,6 @@ export class Connection {
|
|
|
3955
4055
|
let logs;
|
|
3956
4056
|
if ('data' in res.error) {
|
|
3957
4057
|
logs = res.error.data.logs;
|
|
3958
|
-
if (logs && Array.isArray(logs)) {
|
|
3959
|
-
const traceIndent = '\n ';
|
|
3960
|
-
const logTrace = traceIndent + logs.join(traceIndent);
|
|
3961
|
-
console.error(res.error.message, logTrace);
|
|
3962
|
-
}
|
|
3963
4058
|
}
|
|
3964
4059
|
throw new SendTransactionError(
|
|
3965
4060
|
'failed to send transaction: ' + res.error.message,
|
|
@@ -4066,6 +4161,9 @@ export class Connection {
|
|
|
4066
4161
|
Object.values(this._accountChangeSubscriptions).forEach(
|
|
4067
4162
|
s => (s.subscriptionId = null),
|
|
4068
4163
|
);
|
|
4164
|
+
Object.values(this._logsSubscriptions).forEach(
|
|
4165
|
+
s => (s.subscriptionId = null),
|
|
4166
|
+
);
|
|
4069
4167
|
Object.values(this._programAccountChangeSubscriptions).forEach(
|
|
4070
4168
|
s => (s.subscriptionId = null),
|
|
4071
4169
|
);
|
package/src/ed25519-program.ts
CHANGED
|
@@ -30,7 +30,19 @@ export type CreateEd25519InstructionWithPrivateKeyParams = {
|
|
|
30
30
|
instructionIndex?: number;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
const ED25519_INSTRUCTION_LAYOUT = BufferLayout.struct
|
|
33
|
+
const ED25519_INSTRUCTION_LAYOUT = BufferLayout.struct<
|
|
34
|
+
Readonly<{
|
|
35
|
+
messageDataOffset: number;
|
|
36
|
+
messageDataSize: number;
|
|
37
|
+
messageInstructionIndex: number;
|
|
38
|
+
numSignatures: number;
|
|
39
|
+
padding: number;
|
|
40
|
+
publicKeyInstructionIndex: number;
|
|
41
|
+
publicKeyOffset: number;
|
|
42
|
+
signatureInstructionIndex: number;
|
|
43
|
+
signatureOffset: number;
|
|
44
|
+
}>
|
|
45
|
+
>([
|
|
34
46
|
BufferLayout.u8('numSignatures'),
|
|
35
47
|
BufferLayout.u8('padding'),
|
|
36
48
|
BufferLayout.u16('signatureOffset'),
|
|
@@ -82,17 +94,22 @@ export class Ed25519Program {
|
|
|
82
94
|
|
|
83
95
|
const instructionData = Buffer.alloc(messageDataOffset + message.length);
|
|
84
96
|
|
|
97
|
+
const index =
|
|
98
|
+
instructionIndex == null
|
|
99
|
+
? 0xffff // An index of `u16::MAX` makes it default to the current instruction.
|
|
100
|
+
: instructionIndex;
|
|
101
|
+
|
|
85
102
|
ED25519_INSTRUCTION_LAYOUT.encode(
|
|
86
103
|
{
|
|
87
104
|
numSignatures,
|
|
88
105
|
padding: 0,
|
|
89
106
|
signatureOffset,
|
|
90
|
-
signatureInstructionIndex:
|
|
107
|
+
signatureInstructionIndex: index,
|
|
91
108
|
publicKeyOffset,
|
|
92
|
-
publicKeyInstructionIndex:
|
|
109
|
+
publicKeyInstructionIndex: index,
|
|
93
110
|
messageDataOffset,
|
|
94
111
|
messageDataSize: message.length,
|
|
95
|
-
messageInstructionIndex:
|
|
112
|
+
messageInstructionIndex: index,
|
|
96
113
|
},
|
|
97
114
|
instructionData,
|
|
98
115
|
);
|
package/src/instruction.ts
CHANGED
|
@@ -3,21 +3,28 @@ import * as BufferLayout from '@solana/buffer-layout';
|
|
|
3
3
|
|
|
4
4
|
import * as Layout from './layout';
|
|
5
5
|
|
|
6
|
+
export interface IInstructionInputData {
|
|
7
|
+
readonly instruction: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
/**
|
|
7
11
|
* @internal
|
|
8
12
|
*/
|
|
9
|
-
export type InstructionType = {
|
|
13
|
+
export type InstructionType<TInputData extends IInstructionInputData> = {
|
|
10
14
|
/** The Instruction index (from solana upstream program) */
|
|
11
15
|
index: number;
|
|
12
16
|
/** The BufferLayout to use to build data */
|
|
13
|
-
layout: BufferLayout.Layout
|
|
17
|
+
layout: BufferLayout.Layout<TInputData>;
|
|
14
18
|
};
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Populate a buffer of instruction data using an InstructionType
|
|
18
22
|
* @internal
|
|
19
23
|
*/
|
|
20
|
-
export function encodeData
|
|
24
|
+
export function encodeData<TInputData extends IInstructionInputData>(
|
|
25
|
+
type: InstructionType<TInputData>,
|
|
26
|
+
fields?: any,
|
|
27
|
+
): Buffer {
|
|
21
28
|
const allocLength =
|
|
22
29
|
type.layout.span >= 0 ? type.layout.span : Layout.getAlloc(type, fields);
|
|
23
30
|
const data = Buffer.alloc(allocLength);
|
|
@@ -30,8 +37,11 @@ export function encodeData(type: InstructionType, fields?: any): Buffer {
|
|
|
30
37
|
* Decode instruction data buffer using an InstructionType
|
|
31
38
|
* @internal
|
|
32
39
|
*/
|
|
33
|
-
export function decodeData
|
|
34
|
-
|
|
40
|
+
export function decodeData<TInputData extends IInstructionInputData>(
|
|
41
|
+
type: InstructionType<TInputData>,
|
|
42
|
+
buffer: Buffer,
|
|
43
|
+
): TInputData {
|
|
44
|
+
let data: TInputData;
|
|
35
45
|
try {
|
|
36
46
|
data = type.layout.decode(buffer);
|
|
37
47
|
} catch (err) {
|
package/src/layout.ts
CHANGED
|
@@ -4,24 +4,47 @@ import * as BufferLayout from '@solana/buffer-layout';
|
|
|
4
4
|
/**
|
|
5
5
|
* Layout for a public key
|
|
6
6
|
*/
|
|
7
|
-
export const publicKey = (
|
|
8
|
-
property: string = 'publicKey',
|
|
9
|
-
): BufferLayout.Layout => {
|
|
7
|
+
export const publicKey = (property: string = 'publicKey') => {
|
|
10
8
|
return BufferLayout.blob(32, property);
|
|
11
9
|
};
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Layout for a 64bit unsigned value
|
|
15
13
|
*/
|
|
16
|
-
export const uint64 = (property: string = 'uint64')
|
|
14
|
+
export const uint64 = (property: string = 'uint64') => {
|
|
17
15
|
return BufferLayout.blob(8, property);
|
|
18
16
|
};
|
|
19
17
|
|
|
18
|
+
interface IRustStringShim
|
|
19
|
+
extends Omit<
|
|
20
|
+
BufferLayout.Structure<
|
|
21
|
+
Readonly<{
|
|
22
|
+
length: number;
|
|
23
|
+
lengthPadding: number;
|
|
24
|
+
chars: Uint8Array;
|
|
25
|
+
}>
|
|
26
|
+
>,
|
|
27
|
+
'decode' | 'encode' | 'replicate'
|
|
28
|
+
> {
|
|
29
|
+
alloc: (str: string) => number;
|
|
30
|
+
decode: (b: Uint8Array, offset?: number) => string;
|
|
31
|
+
encode: (str: string, b: Uint8Array, offset?: number) => number;
|
|
32
|
+
replicate: (property: string) => this;
|
|
33
|
+
}
|
|
34
|
+
|
|
20
35
|
/**
|
|
21
36
|
* Layout for a Rust String type
|
|
22
37
|
*/
|
|
23
|
-
export const rustString = (
|
|
24
|
-
|
|
38
|
+
export const rustString = (
|
|
39
|
+
property: string = 'string',
|
|
40
|
+
): BufferLayout.Layout<string> => {
|
|
41
|
+
const rsl = BufferLayout.struct<
|
|
42
|
+
Readonly<{
|
|
43
|
+
length?: number;
|
|
44
|
+
lengthPadding?: number;
|
|
45
|
+
chars: Uint8Array;
|
|
46
|
+
}>
|
|
47
|
+
>(
|
|
25
48
|
[
|
|
26
49
|
BufferLayout.u32('length'),
|
|
27
50
|
BufferLayout.u32('lengthPadding'),
|
|
@@ -32,19 +55,21 @@ export const rustString = (property: string = 'string') => {
|
|
|
32
55
|
const _decode = rsl.decode.bind(rsl);
|
|
33
56
|
const _encode = rsl.encode.bind(rsl);
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
const rslShim = rsl as unknown as IRustStringShim;
|
|
59
|
+
|
|
60
|
+
rslShim.decode = (b: Uint8Array, offset?: number) => {
|
|
61
|
+
const data = _decode(b, offset);
|
|
62
|
+
return data['chars'].toString();
|
|
38
63
|
};
|
|
39
64
|
|
|
40
|
-
|
|
65
|
+
rslShim.encode = (str: string, b: Uint8Array, offset?: number) => {
|
|
41
66
|
const data = {
|
|
42
67
|
chars: Buffer.from(str, 'utf8'),
|
|
43
68
|
};
|
|
44
|
-
return _encode(data,
|
|
69
|
+
return _encode(data, b, offset);
|
|
45
70
|
};
|
|
46
71
|
|
|
47
|
-
|
|
72
|
+
rslShim.alloc = (str: string) => {
|
|
48
73
|
return (
|
|
49
74
|
BufferLayout.u32().span +
|
|
50
75
|
BufferLayout.u32().span +
|
|
@@ -52,24 +77,32 @@ export const rustString = (property: string = 'string') => {
|
|
|
52
77
|
);
|
|
53
78
|
};
|
|
54
79
|
|
|
55
|
-
return
|
|
80
|
+
return rslShim;
|
|
56
81
|
};
|
|
57
82
|
|
|
58
83
|
/**
|
|
59
84
|
* Layout for an Authorized object
|
|
60
85
|
*/
|
|
61
86
|
export const authorized = (property: string = 'authorized') => {
|
|
62
|
-
return BufferLayout.struct
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
return BufferLayout.struct<
|
|
88
|
+
Readonly<{
|
|
89
|
+
staker: Uint8Array;
|
|
90
|
+
withdrawer: Uint8Array;
|
|
91
|
+
}>
|
|
92
|
+
>([publicKey('staker'), publicKey('withdrawer')], property);
|
|
66
93
|
};
|
|
67
94
|
|
|
68
95
|
/**
|
|
69
96
|
* Layout for a Lockup object
|
|
70
97
|
*/
|
|
71
98
|
export const lockup = (property: string = 'lockup') => {
|
|
72
|
-
return BufferLayout.struct
|
|
99
|
+
return BufferLayout.struct<
|
|
100
|
+
Readonly<{
|
|
101
|
+
custodian: Uint8Array;
|
|
102
|
+
epoch: number;
|
|
103
|
+
unixTimestamp: number;
|
|
104
|
+
}>
|
|
105
|
+
>(
|
|
73
106
|
[
|
|
74
107
|
BufferLayout.ns64('unixTimestamp'),
|
|
75
108
|
BufferLayout.ns64('epoch'),
|
|
@@ -83,7 +116,14 @@ export const lockup = (property: string = 'lockup') => {
|
|
|
83
116
|
* Layout for a VoteInit object
|
|
84
117
|
*/
|
|
85
118
|
export const voteInit = (property: string = 'voteInit') => {
|
|
86
|
-
return BufferLayout.struct
|
|
119
|
+
return BufferLayout.struct<
|
|
120
|
+
Readonly<{
|
|
121
|
+
authorizedVoter: Uint8Array;
|
|
122
|
+
authorizedWithdrawer: Uint8Array;
|
|
123
|
+
commission: number;
|
|
124
|
+
nodePubkey: Uint8Array;
|
|
125
|
+
}>
|
|
126
|
+
>(
|
|
87
127
|
[
|
|
88
128
|
publicKey('nodePubkey'),
|
|
89
129
|
publicKey('authorizedVoter'),
|
package/src/loader.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {sleep} from './util/sleep';
|
|
|
9
9
|
import type {Connection} from './connection';
|
|
10
10
|
import type {Signer} from './keypair';
|
|
11
11
|
import {SystemProgram} from './system-program';
|
|
12
|
+
import {IInstructionInputData} from './instruction';
|
|
12
13
|
|
|
13
14
|
// Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
|
|
14
15
|
// rest of the Transaction fields
|
|
@@ -137,7 +138,15 @@ export class Loader {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
const dataLayout = BufferLayout.struct
|
|
141
|
+
const dataLayout = BufferLayout.struct<
|
|
142
|
+
Readonly<{
|
|
143
|
+
bytes: number[];
|
|
144
|
+
bytesLength: number;
|
|
145
|
+
bytesLengthPadding: number;
|
|
146
|
+
instruction: number;
|
|
147
|
+
offset: number;
|
|
148
|
+
}>
|
|
149
|
+
>([
|
|
141
150
|
BufferLayout.u32('instruction'),
|
|
142
151
|
BufferLayout.u32('offset'),
|
|
143
152
|
BufferLayout.u32('bytesLength'),
|
|
@@ -160,7 +169,9 @@ export class Loader {
|
|
|
160
169
|
{
|
|
161
170
|
instruction: 0, // Load instruction
|
|
162
171
|
offset,
|
|
163
|
-
bytes,
|
|
172
|
+
bytes: bytes as number[],
|
|
173
|
+
bytesLength: 0,
|
|
174
|
+
bytesLengthPadding: 0,
|
|
164
175
|
},
|
|
165
176
|
data,
|
|
166
177
|
);
|
|
@@ -189,7 +200,9 @@ export class Loader {
|
|
|
189
200
|
|
|
190
201
|
// Finalize the account loaded with program data for execution
|
|
191
202
|
{
|
|
192
|
-
const dataLayout = BufferLayout.struct([
|
|
203
|
+
const dataLayout = BufferLayout.struct<IInstructionInputData>([
|
|
204
|
+
BufferLayout.u32('instruction'),
|
|
205
|
+
]);
|
|
193
206
|
|
|
194
207
|
const data = Buffer.alloc(dataLayout.span);
|
|
195
208
|
dataLayout.encode(
|
package/src/message.ts
CHANGED
|
@@ -118,7 +118,7 @@ export class Message {
|
|
|
118
118
|
|
|
119
119
|
const instructions = this.instructions.map(instruction => {
|
|
120
120
|
const {accounts, programIdIndex} = instruction;
|
|
121
|
-
const data = bs58.decode(instruction.data);
|
|
121
|
+
const data = Array.from(bs58.decode(instruction.data));
|
|
122
122
|
|
|
123
123
|
let keyIndicesCount: number[] = [];
|
|
124
124
|
shortvec.encodeLength(keyIndicesCount, accounts.length);
|
|
@@ -129,7 +129,7 @@ export class Message {
|
|
|
129
129
|
return {
|
|
130
130
|
programIdIndex,
|
|
131
131
|
keyIndicesCount: Buffer.from(keyIndicesCount),
|
|
132
|
-
keyIndices:
|
|
132
|
+
keyIndices: accounts,
|
|
133
133
|
dataLength: Buffer.from(dataCount),
|
|
134
134
|
data,
|
|
135
135
|
};
|
|
@@ -142,7 +142,15 @@ export class Message {
|
|
|
142
142
|
let instructionBufferLength = instructionCount.length;
|
|
143
143
|
|
|
144
144
|
instructions.forEach(instruction => {
|
|
145
|
-
const instructionLayout = BufferLayout.struct
|
|
145
|
+
const instructionLayout = BufferLayout.struct<
|
|
146
|
+
Readonly<{
|
|
147
|
+
data: number[];
|
|
148
|
+
dataLength: Uint8Array;
|
|
149
|
+
keyIndices: number[];
|
|
150
|
+
keyIndicesCount: Uint8Array;
|
|
151
|
+
programIdIndex: number;
|
|
152
|
+
}>
|
|
153
|
+
>([
|
|
146
154
|
BufferLayout.u8('programIdIndex'),
|
|
147
155
|
|
|
148
156
|
BufferLayout.blob(
|
|
@@ -170,7 +178,16 @@ export class Message {
|
|
|
170
178
|
});
|
|
171
179
|
instructionBuffer = instructionBuffer.slice(0, instructionBufferLength);
|
|
172
180
|
|
|
173
|
-
const signDataLayout = BufferLayout.struct
|
|
181
|
+
const signDataLayout = BufferLayout.struct<
|
|
182
|
+
Readonly<{
|
|
183
|
+
keyCount: Uint8Array;
|
|
184
|
+
keys: Uint8Array[];
|
|
185
|
+
numReadonlySignedAccounts: Uint8Array;
|
|
186
|
+
numReadonlyUnsignedAccounts: Uint8Array;
|
|
187
|
+
numRequiredSignatures: Uint8Array;
|
|
188
|
+
recentBlockhash: Uint8Array;
|
|
189
|
+
}>
|
|
190
|
+
>([
|
|
174
191
|
BufferLayout.blob(1, 'numRequiredSignatures'),
|
|
175
192
|
BufferLayout.blob(1, 'numReadonlySignedAccounts'),
|
|
176
193
|
BufferLayout.blob(1, 'numReadonlyUnsignedAccounts'),
|