@solana/web3.js 1.32.1 → 1.35.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.esm.js +381 -13
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +384 -12
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +157 -0
- package/lib/index.esm.js +381 -13
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +384 -12
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +3 -3
- package/lib/index.iife.min.js.map +1 -1
- package/module.flow.js +190 -0
- package/package.json +1 -1
- package/src/connection.ts +10 -1
- package/src/index.ts +1 -0
- package/src/layout.ts +15 -0
- package/src/stake-program.ts +65 -15
- package/src/vote-program.ts +386 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import * as BufferLayout from '@solana/buffer-layout';
|
|
2
|
+
|
|
3
|
+
import {encodeData, decodeData, InstructionType} from './instruction';
|
|
4
|
+
import * as Layout from './layout';
|
|
5
|
+
import {PublicKey} from './publickey';
|
|
6
|
+
import {SystemProgram} from './system-program';
|
|
7
|
+
import {SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY} from './sysvar';
|
|
8
|
+
import {Transaction, TransactionInstruction} from './transaction';
|
|
9
|
+
import {toBuffer} from './util/to-buffer';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Vote account info
|
|
13
|
+
*/
|
|
14
|
+
export class VoteInit {
|
|
15
|
+
nodePubkey: PublicKey;
|
|
16
|
+
authorizedVoter: PublicKey;
|
|
17
|
+
authorizedWithdrawer: PublicKey;
|
|
18
|
+
commission: number; /** [0, 100] */
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
nodePubkey: PublicKey,
|
|
22
|
+
authorizedVoter: PublicKey,
|
|
23
|
+
authorizedWithdrawer: PublicKey,
|
|
24
|
+
commission: number,
|
|
25
|
+
) {
|
|
26
|
+
this.nodePubkey = nodePubkey;
|
|
27
|
+
this.authorizedVoter = authorizedVoter;
|
|
28
|
+
this.authorizedWithdrawer = authorizedWithdrawer;
|
|
29
|
+
this.commission = commission;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create vote account transaction params
|
|
35
|
+
*/
|
|
36
|
+
export type CreateVoteAccountParams = {
|
|
37
|
+
fromPubkey: PublicKey;
|
|
38
|
+
votePubkey: PublicKey;
|
|
39
|
+
voteInit: VoteInit;
|
|
40
|
+
lamports: number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* InitializeAccount instruction params
|
|
45
|
+
*/
|
|
46
|
+
export type InitializeAccountParams = {
|
|
47
|
+
votePubkey: PublicKey;
|
|
48
|
+
nodePubkey: PublicKey;
|
|
49
|
+
voteInit: VoteInit;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Authorize instruction params
|
|
54
|
+
*/
|
|
55
|
+
export type AuthorizeVoteParams = {
|
|
56
|
+
votePubkey: PublicKey;
|
|
57
|
+
/** Current vote or withdraw authority, depending on `voteAuthorizationType` */
|
|
58
|
+
authorizedPubkey: PublicKey;
|
|
59
|
+
newAuthorizedPubkey: PublicKey;
|
|
60
|
+
voteAuthorizationType: VoteAuthorizationType;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Withdraw from vote account transaction params
|
|
65
|
+
*/
|
|
66
|
+
export type WithdrawFromVoteAccountParams = {
|
|
67
|
+
votePubkey: PublicKey;
|
|
68
|
+
authorizedWithdrawerPubkey: PublicKey;
|
|
69
|
+
lamports: number;
|
|
70
|
+
toPubkey: PublicKey;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Vote Instruction class
|
|
75
|
+
*/
|
|
76
|
+
export class VoteInstruction {
|
|
77
|
+
/**
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
constructor() {}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Decode a vote instruction and retrieve the instruction type.
|
|
84
|
+
*/
|
|
85
|
+
static decodeInstructionType(
|
|
86
|
+
instruction: TransactionInstruction,
|
|
87
|
+
): VoteInstructionType {
|
|
88
|
+
this.checkProgramId(instruction.programId);
|
|
89
|
+
|
|
90
|
+
const instructionTypeLayout = BufferLayout.u32('instruction');
|
|
91
|
+
const typeIndex = instructionTypeLayout.decode(instruction.data);
|
|
92
|
+
|
|
93
|
+
let type: VoteInstructionType | undefined;
|
|
94
|
+
for (const [ixType, layout] of Object.entries(VOTE_INSTRUCTION_LAYOUTS)) {
|
|
95
|
+
if (layout.index == typeIndex) {
|
|
96
|
+
type = ixType as VoteInstructionType;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!type) {
|
|
102
|
+
throw new Error('Instruction type incorrect; not a VoteInstruction');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return type;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Decode an initialize vote instruction and retrieve the instruction params.
|
|
110
|
+
*/
|
|
111
|
+
static decodeInitializeAccount(
|
|
112
|
+
instruction: TransactionInstruction,
|
|
113
|
+
): InitializeAccountParams {
|
|
114
|
+
this.checkProgramId(instruction.programId);
|
|
115
|
+
this.checkKeyLength(instruction.keys, 4);
|
|
116
|
+
|
|
117
|
+
const {voteInit} = decodeData(
|
|
118
|
+
VOTE_INSTRUCTION_LAYOUTS.InitializeAccount,
|
|
119
|
+
instruction.data,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
votePubkey: instruction.keys[0].pubkey,
|
|
124
|
+
nodePubkey: instruction.keys[3].pubkey,
|
|
125
|
+
voteInit: new VoteInit(
|
|
126
|
+
new PublicKey(voteInit.nodePubkey),
|
|
127
|
+
new PublicKey(voteInit.authorizedVoter),
|
|
128
|
+
new PublicKey(voteInit.authorizedWithdrawer),
|
|
129
|
+
voteInit.commission,
|
|
130
|
+
),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
136
|
+
*/
|
|
137
|
+
static decodeAuthorize(
|
|
138
|
+
instruction: TransactionInstruction,
|
|
139
|
+
): AuthorizeVoteParams {
|
|
140
|
+
this.checkProgramId(instruction.programId);
|
|
141
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
142
|
+
|
|
143
|
+
const {newAuthorized, voteAuthorizationType} = decodeData(
|
|
144
|
+
VOTE_INSTRUCTION_LAYOUTS.Authorize,
|
|
145
|
+
instruction.data,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
votePubkey: instruction.keys[0].pubkey,
|
|
150
|
+
authorizedPubkey: instruction.keys[2].pubkey,
|
|
151
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
152
|
+
voteAuthorizationType: {
|
|
153
|
+
index: voteAuthorizationType,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Decode a withdraw instruction and retrieve the instruction params.
|
|
160
|
+
*/
|
|
161
|
+
static decodeWithdraw(
|
|
162
|
+
instruction: TransactionInstruction,
|
|
163
|
+
): WithdrawFromVoteAccountParams {
|
|
164
|
+
this.checkProgramId(instruction.programId);
|
|
165
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
166
|
+
|
|
167
|
+
const {lamports} = decodeData(
|
|
168
|
+
VOTE_INSTRUCTION_LAYOUTS.Withdraw,
|
|
169
|
+
instruction.data,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
votePubkey: instruction.keys[0].pubkey,
|
|
174
|
+
authorizedWithdrawerPubkey: instruction.keys[2].pubkey,
|
|
175
|
+
lamports,
|
|
176
|
+
toPubkey: instruction.keys[1].pubkey,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
static checkProgramId(programId: PublicKey) {
|
|
184
|
+
if (!programId.equals(VoteProgram.programId)) {
|
|
185
|
+
throw new Error('invalid instruction; programId is not VoteProgram');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @internal
|
|
191
|
+
*/
|
|
192
|
+
static checkKeyLength(keys: Array<any>, expectedLength: number) {
|
|
193
|
+
if (keys.length < expectedLength) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* An enumeration of valid VoteInstructionType's
|
|
203
|
+
*/
|
|
204
|
+
export type VoteInstructionType =
|
|
205
|
+
| 'Authorize'
|
|
206
|
+
| 'InitializeAccount'
|
|
207
|
+
| 'Withdraw';
|
|
208
|
+
|
|
209
|
+
const VOTE_INSTRUCTION_LAYOUTS: {
|
|
210
|
+
[type in VoteInstructionType]: InstructionType;
|
|
211
|
+
} = Object.freeze({
|
|
212
|
+
InitializeAccount: {
|
|
213
|
+
index: 0,
|
|
214
|
+
layout: BufferLayout.struct([
|
|
215
|
+
BufferLayout.u32('instruction'),
|
|
216
|
+
Layout.voteInit(),
|
|
217
|
+
]),
|
|
218
|
+
},
|
|
219
|
+
Authorize: {
|
|
220
|
+
index: 1,
|
|
221
|
+
layout: BufferLayout.struct([
|
|
222
|
+
BufferLayout.u32('instruction'),
|
|
223
|
+
Layout.publicKey('newAuthorized'),
|
|
224
|
+
BufferLayout.u32('voteAuthorizationType'),
|
|
225
|
+
]),
|
|
226
|
+
},
|
|
227
|
+
Withdraw: {
|
|
228
|
+
index: 3,
|
|
229
|
+
layout: BufferLayout.struct([
|
|
230
|
+
BufferLayout.u32('instruction'),
|
|
231
|
+
BufferLayout.ns64('lamports'),
|
|
232
|
+
]),
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* VoteAuthorize type
|
|
238
|
+
*/
|
|
239
|
+
export type VoteAuthorizationType = {
|
|
240
|
+
/** The VoteAuthorize index (from solana-vote-program) */
|
|
241
|
+
index: number;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* An enumeration of valid VoteAuthorization layouts.
|
|
246
|
+
*/
|
|
247
|
+
export const VoteAuthorizationLayout = Object.freeze({
|
|
248
|
+
Voter: {
|
|
249
|
+
index: 0,
|
|
250
|
+
},
|
|
251
|
+
Withdrawer: {
|
|
252
|
+
index: 1,
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Factory class for transactions to interact with the Vote program
|
|
258
|
+
*/
|
|
259
|
+
export class VoteProgram {
|
|
260
|
+
/**
|
|
261
|
+
* @internal
|
|
262
|
+
*/
|
|
263
|
+
constructor() {}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Public key that identifies the Vote program
|
|
267
|
+
*/
|
|
268
|
+
static programId: PublicKey = new PublicKey(
|
|
269
|
+
'Vote111111111111111111111111111111111111111',
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Max space of a Vote account
|
|
274
|
+
*
|
|
275
|
+
* This is generated from the solana-vote-program VoteState struct as
|
|
276
|
+
* `VoteState::size_of()`:
|
|
277
|
+
* https://docs.rs/solana-vote-program/1.9.5/solana_vote_program/vote_state/struct.VoteState.html#method.size_of
|
|
278
|
+
*/
|
|
279
|
+
static space: number = 3731;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Generate an Initialize instruction.
|
|
283
|
+
*/
|
|
284
|
+
static initializeAccount(
|
|
285
|
+
params: InitializeAccountParams,
|
|
286
|
+
): TransactionInstruction {
|
|
287
|
+
const {votePubkey, nodePubkey, voteInit} = params;
|
|
288
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.InitializeAccount;
|
|
289
|
+
const data = encodeData(type, {
|
|
290
|
+
voteInit: {
|
|
291
|
+
nodePubkey: toBuffer(voteInit.nodePubkey.toBuffer()),
|
|
292
|
+
authorizedVoter: toBuffer(voteInit.authorizedVoter.toBuffer()),
|
|
293
|
+
authorizedWithdrawer: toBuffer(
|
|
294
|
+
voteInit.authorizedWithdrawer.toBuffer(),
|
|
295
|
+
),
|
|
296
|
+
commission: voteInit.commission,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
const instructionData = {
|
|
300
|
+
keys: [
|
|
301
|
+
{pubkey: votePubkey, isSigner: false, isWritable: true},
|
|
302
|
+
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
|
|
303
|
+
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
|
304
|
+
{pubkey: nodePubkey, isSigner: true, isWritable: false},
|
|
305
|
+
],
|
|
306
|
+
programId: this.programId,
|
|
307
|
+
data,
|
|
308
|
+
};
|
|
309
|
+
return new TransactionInstruction(instructionData);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Generate a transaction that creates a new Vote account.
|
|
314
|
+
*/
|
|
315
|
+
static createAccount(params: CreateVoteAccountParams): Transaction {
|
|
316
|
+
const transaction = new Transaction();
|
|
317
|
+
transaction.add(
|
|
318
|
+
SystemProgram.createAccount({
|
|
319
|
+
fromPubkey: params.fromPubkey,
|
|
320
|
+
newAccountPubkey: params.votePubkey,
|
|
321
|
+
lamports: params.lamports,
|
|
322
|
+
space: this.space,
|
|
323
|
+
programId: this.programId,
|
|
324
|
+
}),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
return transaction.add(
|
|
328
|
+
this.initializeAccount({
|
|
329
|
+
votePubkey: params.votePubkey,
|
|
330
|
+
nodePubkey: params.voteInit.nodePubkey,
|
|
331
|
+
voteInit: params.voteInit,
|
|
332
|
+
}),
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account.
|
|
338
|
+
*/
|
|
339
|
+
static authorize(params: AuthorizeVoteParams): Transaction {
|
|
340
|
+
const {
|
|
341
|
+
votePubkey,
|
|
342
|
+
authorizedPubkey,
|
|
343
|
+
newAuthorizedPubkey,
|
|
344
|
+
voteAuthorizationType,
|
|
345
|
+
} = params;
|
|
346
|
+
|
|
347
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.Authorize;
|
|
348
|
+
const data = encodeData(type, {
|
|
349
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
350
|
+
voteAuthorizationType: voteAuthorizationType.index,
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const keys = [
|
|
354
|
+
{pubkey: votePubkey, isSigner: false, isWritable: true},
|
|
355
|
+
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
|
356
|
+
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
|
357
|
+
];
|
|
358
|
+
|
|
359
|
+
return new Transaction().add({
|
|
360
|
+
keys,
|
|
361
|
+
programId: this.programId,
|
|
362
|
+
data,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Generate a transaction to withdraw from a Vote account.
|
|
368
|
+
*/
|
|
369
|
+
static withdraw(params: WithdrawFromVoteAccountParams): Transaction {
|
|
370
|
+
const {votePubkey, authorizedWithdrawerPubkey, lamports, toPubkey} = params;
|
|
371
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.Withdraw;
|
|
372
|
+
const data = encodeData(type, {lamports});
|
|
373
|
+
|
|
374
|
+
const keys = [
|
|
375
|
+
{pubkey: votePubkey, isSigner: false, isWritable: true},
|
|
376
|
+
{pubkey: toPubkey, isSigner: false, isWritable: true},
|
|
377
|
+
{pubkey: authorizedWithdrawerPubkey, isSigner: true, isWritable: false},
|
|
378
|
+
];
|
|
379
|
+
|
|
380
|
+
return new Transaction().add({
|
|
381
|
+
keys,
|
|
382
|
+
programId: this.programId,
|
|
383
|
+
data,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|