@exodus/solana-lib 1.7.4 → 1.7.6

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.
@@ -0,0 +1,180 @@
1
+ import * as BufferLayout from '@exodus/buffer-layout'
2
+
3
+ import { encodeData, decodeData } from './instruction'
4
+ import { PublicKey } from './publickey'
5
+ import { TransactionInstruction } from './transaction'
6
+
7
+ // 1 microLamport = 0.000001 lamports
8
+
9
+ /**
10
+ * Compute Budget Instruction class
11
+ */
12
+ // eslint-disable-next-line unicorn/no-static-only-class
13
+ export class ComputeBudgetInstruction {
14
+ /**
15
+ * Decode a compute budget instruction and retrieve the instruction type.
16
+ */
17
+ static decodeInstructionType(instruction) {
18
+ this.checkProgramId(instruction.programId)
19
+
20
+ const instructionTypeLayout = BufferLayout.u8('instruction')
21
+ const typeIndex = instructionTypeLayout.decode(instruction.data)
22
+
23
+ let type
24
+ for (const [ixType, layout] of Object.entries(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS)) {
25
+ if (layout.index === typeIndex) {
26
+ type = ixType
27
+ break
28
+ }
29
+ }
30
+
31
+ if (!type) {
32
+ throw new Error('Instruction type incorrect; not a ComputeBudgetInstruction')
33
+ }
34
+
35
+ return type
36
+ }
37
+
38
+ /**
39
+ * Decode request units compute budget instruction and retrieve the instruction params.
40
+ */
41
+ static decodeRequestUnits(instruction) {
42
+ this.checkProgramId(instruction.programId)
43
+ const { units, additionalFee } = decodeData(
44
+ COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits,
45
+ instruction.data
46
+ )
47
+ return { units, additionalFee }
48
+ }
49
+
50
+ /**
51
+ * Decode request heap frame compute budget instruction and retrieve the instruction params.
52
+ */
53
+ static decodeRequestHeapFrame(instruction) {
54
+ this.checkProgramId(instruction.programId)
55
+ const { bytes } = decodeData(
56
+ COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame,
57
+ instruction.data
58
+ )
59
+ return { bytes }
60
+ }
61
+
62
+ /**
63
+ * Decode set compute unit limit compute budget instruction and retrieve the instruction params.
64
+ */
65
+ static decodeSetComputeUnitLimit(instruction) {
66
+ this.checkProgramId(instruction.programId)
67
+ const { units } = decodeData(
68
+ COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.SetComputeUnitLimit,
69
+ instruction.data
70
+ )
71
+ return { units }
72
+ }
73
+
74
+ /**
75
+ * Decode set compute unit price compute budget instruction and retrieve the instruction params.
76
+ */
77
+ static decodeSetComputeUnitPrice(instruction) {
78
+ this.checkProgramId(instruction.programId)
79
+ const { microLamports } = decodeData(
80
+ COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.SetComputeUnitPrice,
81
+ instruction.data
82
+ )
83
+ return { microLamports }
84
+ }
85
+
86
+ /**
87
+ * @internal
88
+ */
89
+ static checkProgramId(programId) {
90
+ if (!programId.equals(ComputeBudgetProgram.programId)) {
91
+ throw new Error('invalid instruction; programId is not ComputeBudgetProgram')
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * An enumeration of valid ComputeBudget InstructionType's
98
+ * @internal
99
+ */
100
+ export const COMPUTE_BUDGET_INSTRUCTION_LAYOUTS = Object.freeze({
101
+ RequestUnits: {
102
+ index: 0,
103
+ layout: BufferLayout.struct([
104
+ BufferLayout.u8('instruction'),
105
+ BufferLayout.u32('units'),
106
+ BufferLayout.u32('additionalFee'),
107
+ ]),
108
+ },
109
+ RequestHeapFrame: {
110
+ index: 1,
111
+ layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('bytes')]),
112
+ },
113
+ SetComputeUnitLimit: {
114
+ index: 2,
115
+ layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('units')]),
116
+ },
117
+ SetComputeUnitPrice: {
118
+ index: 3,
119
+ layout: BufferLayout.struct([
120
+ BufferLayout.u8('instruction'),
121
+ BufferLayout.ns64('microLamports'),
122
+ ]),
123
+ },
124
+ })
125
+
126
+ /**
127
+ * Factory class for transaction instructions to interact with the Compute Budget program
128
+ */
129
+ // eslint-disable-next-line unicorn/no-static-only-class
130
+ export class ComputeBudgetProgram {
131
+ /**
132
+ * Public key that identifies the Compute Budget program
133
+ */
134
+ static programId = new PublicKey('ComputeBudget111111111111111111111111111111')
135
+
136
+ /**
137
+ * @deprecated Instead, call {@link setComputeUnitLimit} and/or {@link setComputeUnitPrice}
138
+ */
139
+ static requestUnits(params) {
140
+ const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits
141
+ const data = encodeData(type, params)
142
+ return new TransactionInstruction({
143
+ keys: [],
144
+ programId: this.programId,
145
+ data,
146
+ })
147
+ }
148
+
149
+ static requestHeapFrame(params) {
150
+ const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame
151
+ const data = encodeData(type, params)
152
+ return new TransactionInstruction({
153
+ keys: [],
154
+ programId: this.programId,
155
+ data,
156
+ })
157
+ }
158
+
159
+ static setComputeUnitLimit(params) {
160
+ const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.SetComputeUnitLimit
161
+ const data = encodeData(type, params)
162
+ return new TransactionInstruction({
163
+ keys: [],
164
+ programId: this.programId,
165
+ data,
166
+ })
167
+ }
168
+
169
+ static setComputeUnitPrice(params) {
170
+ const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.SetComputeUnitPrice
171
+ const data = encodeData(type, {
172
+ microLamports: Number(params.microLamports), // replaced from BigInt
173
+ })
174
+ return new TransactionInstruction({
175
+ keys: [],
176
+ programId: this.programId,
177
+ data,
178
+ })
179
+ }
180
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Maximum over-the-wire size of a Transaction
3
+ *
4
+ * 1280 is IPv6 minimum MTU
5
+ * 40 bytes is the size of the IPv6 header
6
+ * 8 bytes is the size of the fragment header
7
+ */
8
+ export const PACKET_DATA_SIZE = 1280 - 40 - 8
@@ -4,6 +4,8 @@ export * from './message'
4
4
  export * from './nonce-account'
5
5
  export * from './publickey'
6
6
  export * from './system-program'
7
+ export * from './compute-budget-program'
7
8
  export * from './stake-program'
8
9
  export * from './sysvar'
9
10
  export * from './transaction'
11
+ export * from './constants'
@@ -4,7 +4,7 @@ import * as BufferLayout from '@exodus/buffer-layout'
4
4
  import { PublicKey } from './publickey'
5
5
 
6
6
  import * as Layout from './utils/layout'
7
- import { PACKET_DATA_SIZE } from './transaction'
7
+ import { PACKET_DATA_SIZE } from './constants'
8
8
  import * as shortvec from './utils/shortvec-encoding'
9
9
 
10
10
  /**
@@ -73,23 +73,24 @@ export class Message {
73
73
  if (index < 0) {
74
74
  throw new Error(`unknown signer: ${signer.toString()}`)
75
75
  }
76
+
76
77
  return index
77
78
  }
78
79
 
79
80
  serialize() {
80
81
  const numKeys = this.accountKeys.length
81
82
 
82
- let keyCount = []
83
+ const keyCount = []
83
84
  shortvec.encodeLength(keyCount, numKeys)
84
85
 
85
86
  const instructions = this.instructions.map((instruction) => {
86
87
  const { accounts, programIdIndex } = instruction
87
88
  const data = bs58.decode(instruction.data)
88
89
 
89
- let keyIndicesCount = []
90
+ const keyIndicesCount = []
90
91
  shortvec.encodeLength(keyIndicesCount, accounts.length)
91
92
 
92
- let dataCount = []
93
+ const dataCount = []
93
94
  shortvec.encodeLength(dataCount, data.length)
94
95
 
95
96
  return {
@@ -101,7 +102,7 @@ export class Message {
101
102
  }
102
103
  })
103
104
 
104
- let instructionCount = []
105
+ const instructionCount = []
105
106
  shortvec.encodeLength(instructionCount, instructions.length)
106
107
  let instructionBuffer = Buffer.alloc(PACKET_DATA_SIZE)
107
108
  Buffer.from(instructionCount).copy(instructionBuffer)
@@ -143,7 +144,7 @@ export class Message {
143
144
  recentBlockhash: bs58.decode(this.recentBlockhash),
144
145
  }
145
146
 
146
- let signData = Buffer.alloc(2048)
147
+ const signData = Buffer.alloc(2048)
147
148
  const length = signDataLayout.encode(transaction, signData)
148
149
  instructionBuffer.copy(signData, length)
149
150
  return signData.slice(0, length + instructionBuffer.length)
@@ -161,7 +162,7 @@ export class Message {
161
162
  const numReadonlyUnsignedAccounts = byteArray.shift()
162
163
 
163
164
  const accountCount = shortvec.decodeLength(byteArray)
164
- let accountKeys = []
165
+ const accountKeys = []
165
166
  for (let i = 0; i < accountCount; i++) {
166
167
  const account = byteArray.slice(0, PUBKEY_LENGTH)
167
168
  byteArray = byteArray.slice(PUBKEY_LENGTH)
@@ -172,9 +173,9 @@ export class Message {
172
173
  byteArray = byteArray.slice(PUBKEY_LENGTH)
173
174
 
174
175
  const instructionCount = shortvec.decodeLength(byteArray)
175
- let instructions = []
176
+ const instructions = []
176
177
  for (let i = 0; i < instructionCount; i++) {
177
- let instruction = {}
178
+ const instruction = Object.create(null)
178
179
  instruction.programIdIndex = byteArray.shift()
179
180
  const accountCount = shortvec.decodeLength(byteArray)
180
181
  instruction.accounts = byteArray.slice(0, accountCount)
@@ -4,7 +4,7 @@ import nacl from 'tweetnacl'
4
4
  import createHash from 'create-hash'
5
5
 
6
6
  // $FlowFixMe
7
- let naclLowLevel = nacl.lowlevel
7
+ const naclLowLevel = nacl.lowlevel
8
8
 
9
9
  /**
10
10
  * Maximum length of derived pubkey seed
@@ -27,6 +27,7 @@ export class PublicKey {
27
27
  if (decoded.length !== 32) {
28
28
  throw new Error(`Invalid public key input`)
29
29
  }
30
+
30
31
  this._bn = new BN(decoded)
31
32
  } else {
32
33
  this._bn = new BN(value)
@@ -100,14 +101,16 @@ export class PublicKey {
100
101
  let address
101
102
  while (nonce !== 0) {
102
103
  try {
103
- const seedsWithNonce = seeds.concat(Buffer.from([nonce]))
104
+ const seedsWithNonce = [...seeds, Buffer.from([nonce])]
104
105
  address = this.createProgramAddress(seedsWithNonce, programId)
105
- } catch (err) {
106
+ } catch {
106
107
  nonce--
107
108
  continue
108
109
  }
110
+
109
111
  return [address, nonce]
110
112
  }
113
+
111
114
  throw new Error('Unable to find a viable program address nonce')
112
115
  }
113
116
 
@@ -121,9 +124,7 @@ export class PublicKey {
121
124
  Buffer.from(seed),
122
125
  programId.toBuffer(),
123
126
  ])
124
- const hash = createHash('sha256')
125
- .update(buffer)
126
- .digest('hex')
127
+ const hash = createHash('sha256').update(buffer).digest('hex')
127
128
  return new PublicKey(Buffer.from(hash, 'hex'))
128
129
  }
129
130
 
@@ -132,20 +133,20 @@ export class PublicKey {
132
133
  */
133
134
  static createProgramAddress(seeds, programId) {
134
135
  let buffer = Buffer.alloc(0)
135
- seeds.forEach(function(seed) {
136
+ seeds.forEach(function (seed) {
136
137
  if (seed.length > MAX_SEED_LENGTH) {
137
138
  throw new Error('Max seed length exceeded')
138
139
  }
140
+
139
141
  buffer = Buffer.concat([buffer, Buffer.from(seed)])
140
142
  })
141
143
  buffer = Buffer.concat([buffer, programId.toBuffer(), Buffer.from('ProgramDerivedAddress')])
142
- let hash = createHash('sha256')
143
- .update(buffer)
144
- .digest('hex')
145
- let publicKeyBytes = new BN(hash, 16).toArray(null, 32)
144
+ const hash = createHash('sha256').update(buffer).digest('hex')
145
+ const publicKeyBytes = new BN(hash, 16).toArray(null, 32)
146
146
  if (isOnCurve(publicKeyBytes)) {
147
147
  throw new Error('Invalid seeds, address must fall off the curve')
148
148
  }
149
+
149
150
  return new PublicKey(publicKeyBytes)
150
151
  }
151
152
  }
@@ -154,15 +155,15 @@ export class PublicKey {
154
155
  // This function and its dependents were sourced from:
155
156
  // https://github.com/dchest/tweetnacl-js/blob/f1ec050ceae0861f34280e62498b1d3ed9c350c6/nacl.js#L792
156
157
  function isOnCurve(p) {
157
- let r = [naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf()]
158
+ const r = [naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf()]
158
159
 
159
- let t = naclLowLevel.gf()
160
- let chk = naclLowLevel.gf()
161
- let num = naclLowLevel.gf()
162
- let den = naclLowLevel.gf()
163
- let den2 = naclLowLevel.gf()
164
- let den4 = naclLowLevel.gf()
165
- let den6 = naclLowLevel.gf()
160
+ const t = naclLowLevel.gf()
161
+ const chk = naclLowLevel.gf()
162
+ const num = naclLowLevel.gf()
163
+ const den = naclLowLevel.gf()
164
+ const den2 = naclLowLevel.gf()
165
+ const den4 = naclLowLevel.gf()
166
+ const den6 = naclLowLevel.gf()
166
167
 
167
168
  naclLowLevel.set25519(r[2], gf1)
168
169
  naclLowLevel.unpack25519(r[1], p)
@@ -193,24 +194,10 @@ function isOnCurve(p) {
193
194
  return 1
194
195
  }
195
196
 
196
- let gf1 = naclLowLevel.gf([1])
197
- let I = naclLowLevel.gf([
198
- 0xa0b0,
199
- 0x4a0e,
200
- 0x1b27,
201
- 0xc4ee,
202
- 0xe478,
203
- 0xad2f,
204
- 0x1806,
205
- 0x2f43,
206
- 0xd7a7,
207
- 0x3dfb,
208
- 0x0099,
209
- 0x2b4d,
210
- 0xdf0b,
211
- 0x4fc1,
212
- 0x2480,
213
- 0x2b83,
197
+ const gf1 = naclLowLevel.gf([1])
198
+ const I = naclLowLevel.gf([
199
+ 0xa0_b0, 0x4a_0e, 0x1b_27, 0xc4_ee, 0xe4_78, 0xad_2f, 0x18_06, 0x2f_43, 0xd7_a7, 0x3d_fb, 0x00_99,
200
+ 0x2b_4d, 0xdf_0b, 0x4f_c1, 0x24_80, 0x2b_83,
214
201
  ])
215
202
 
216
203
  function neq25519(a, b) {
@@ -176,11 +176,11 @@ export const STAKE_INSTRUCTION_LAYOUTS = Object.freeze({
176
176
  /**
177
177
  * Stake Instruction class
178
178
  */
179
- export class StakeInstruction {
179
+ export const StakeInstruction = {
180
180
  /**
181
181
  * Decode a stake instruction and retrieve the instruction type.
182
182
  */
183
- static decodeInstructionType(instruction) {
183
+ decodeInstructionType(instruction) {
184
184
  this.checkProgramId(instruction.programId)
185
185
 
186
186
  const instructionTypeLayout = BufferLayout.u32('instruction')
@@ -198,12 +198,12 @@ export class StakeInstruction {
198
198
  }
199
199
 
200
200
  return type
201
- }
201
+ },
202
202
 
203
203
  /**
204
204
  * Decode a initialize stake instruction and retrieve the instruction params.
205
205
  */
206
- static decodeInitialize(instruction) {
206
+ decodeInitialize(instruction) {
207
207
  this.checkProgramId(instruction.programId)
208
208
  this.checkKeyLength(instruction.keys, 2)
209
209
 
@@ -220,12 +220,12 @@ export class StakeInstruction {
220
220
  ),
221
221
  lockup: new Lockup(lockup.unixTimestamp, lockup.epoch, new PublicKey(lockup.custodian)),
222
222
  }
223
- }
223
+ },
224
224
 
225
225
  /**
226
226
  * Decode a delegate stake instruction and retrieve the instruction params.
227
227
  */
228
- static decodeDelegate(instruction) {
228
+ decodeDelegate(instruction) {
229
229
  this.checkProgramId(instruction.programId)
230
230
  this.checkKeyLength(instruction.keys, 6)
231
231
  decodeData(STAKE_INSTRUCTION_LAYOUTS.Delegate, instruction.data)
@@ -235,12 +235,12 @@ export class StakeInstruction {
235
235
  votePubkey: instruction.keys[1].pubkey,
236
236
  authorizedPubkey: instruction.keys[5].pubkey,
237
237
  }
238
- }
238
+ },
239
239
 
240
240
  /**
241
241
  * Decode a withdraw stake instruction and retrieve the instruction params.
242
242
  */
243
- static decodeWithdraw(instruction) {
243
+ decodeWithdraw(instruction) {
244
244
  this.checkProgramId(instruction.programId)
245
245
  this.checkKeyLength(instruction.keys, 5)
246
246
  const { lamports } = decodeData(STAKE_INSTRUCTION_LAYOUTS.Withdraw, instruction.data)
@@ -251,12 +251,12 @@ export class StakeInstruction {
251
251
  authorizedPubkey: instruction.keys[4].pubkey,
252
252
  lamports,
253
253
  }
254
- }
254
+ },
255
255
 
256
256
  /**
257
257
  * Decode a deactivate stake instruction and retrieve the instruction params.
258
258
  */
259
- static decodeDeactivate(instruction) {
259
+ decodeDeactivate(instruction) {
260
260
  this.checkProgramId(instruction.programId)
261
261
  this.checkKeyLength(instruction.keys, 3)
262
262
  decodeData(STAKE_INSTRUCTION_LAYOUTS.Deactivate, instruction.data)
@@ -265,27 +265,27 @@ export class StakeInstruction {
265
265
  stakePubkey: instruction.keys[0].pubkey,
266
266
  authorizedPubkey: instruction.keys[2].pubkey,
267
267
  }
268
- }
268
+ },
269
269
 
270
270
  /**
271
271
  * @private
272
272
  */
273
- static checkProgramId(programId) {
273
+ checkProgramId(programId) {
274
274
  if (!programId.equals(StakeProgram.programId)) {
275
275
  throw new Error('invalid instruction; programId is not StakeProgram')
276
276
  }
277
- }
277
+ },
278
278
 
279
279
  /**
280
280
  * @private
281
281
  */
282
- static checkKeyLength(keys, expectedLength) {
282
+ checkKeyLength(keys, expectedLength) {
283
283
  if (keys.length < expectedLength) {
284
284
  throw new Error(
285
285
  `invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`
286
286
  )
287
287
  }
288
- }
288
+ },
289
289
  }
290
290
 
291
291
  /**
@@ -303,13 +303,13 @@ export const StakeAuthorizationLayout = Object.freeze({
303
303
  /**
304
304
  * Factory class for transactions to interact with the Stake program
305
305
  */
306
- export class StakeProgram {
306
+ export const StakeProgram = {
307
307
  /**
308
308
  * Public key that identifies the Stake program
309
309
  */
310
- static get programId() {
310
+ get programId() {
311
311
  return new PublicKey('Stake11111111111111111111111111111111111111')
312
- }
312
+ },
313
313
 
314
314
  /**
315
315
  * Max space of a Stake account
@@ -318,14 +318,14 @@ export class StakeProgram {
318
318
  * `std::mem::size_of::<StakeState>()`:
319
319
  * https://docs.rs/solana-stake-program/1.4.4/solana_stake_program/stake_state/enum.StakeState.html
320
320
  */
321
- static get space() {
321
+ get space() {
322
322
  return 200
323
- }
323
+ },
324
324
 
325
325
  /**
326
326
  * Generate an Initialize instruction to add to a Stake Create transaction
327
327
  */
328
- static initialize(params) {
328
+ initialize(params) {
329
329
  const { stakePubkey, authorized, lockup } = params
330
330
  const type = STAKE_INSTRUCTION_LAYOUTS.Initialize
331
331
  const data = encodeData(type, {
@@ -348,13 +348,13 @@ export class StakeProgram {
348
348
  data,
349
349
  }
350
350
  return new TransactionInstruction(instructionData)
351
- }
351
+ },
352
352
 
353
353
  /**
354
354
  * Generate a Transaction that creates a new Stake account at
355
355
  * an address generated with `from`, a seed, and the Stake programId
356
356
  */
357
- static createAccountWithSeed(params) {
357
+ createAccountWithSeed(params) {
358
358
  const transaction = new Transaction()
359
359
  transaction.add(
360
360
  SystemProgram.createAccountWithSeed({
@@ -370,12 +370,12 @@ export class StakeProgram {
370
370
 
371
371
  const { stakePubkey, authorized, lockup } = params
372
372
  return transaction.add(this.initialize({ stakePubkey, authorized, lockup }))
373
- }
373
+ },
374
374
 
375
375
  /**
376
376
  * Generate a Transaction that creates a new Stake account
377
377
  */
378
- static createAccount(params) {
378
+ createAccount(params) {
379
379
  const transaction = new Transaction()
380
380
  transaction.add(
381
381
  SystemProgram.createAccount({
@@ -389,14 +389,14 @@ export class StakeProgram {
389
389
 
390
390
  const { stakePubkey, authorized, lockup } = params
391
391
  return transaction.add(this.initialize({ stakePubkey, authorized, lockup }))
392
- }
392
+ },
393
393
 
394
394
  /**
395
395
  * Generate a Transaction that delegates Stake tokens to a validator
396
396
  * Vote PublicKey. This transaction can also be used to redelegate Stake
397
397
  * to a new validator Vote PublicKey.
398
398
  */
399
- static delegate(params) {
399
+ delegate(params) {
400
400
  const { stakePubkey, authorizedPubkey, votePubkey } = params
401
401
 
402
402
  const type = STAKE_INSTRUCTION_LAYOUTS.Delegate
@@ -418,12 +418,12 @@ export class StakeProgram {
418
418
  programId: this.programId,
419
419
  data,
420
420
  })
421
- }
421
+ },
422
422
 
423
423
  /**
424
424
  * Generate a Transaction that withdraws deactivated Stake tokens.
425
425
  */
426
- static withdraw(params) {
426
+ withdraw(params) {
427
427
  const { stakePubkey, authorizedPubkey, toPubkey, lamports } = params
428
428
  const type = STAKE_INSTRUCTION_LAYOUTS.Withdraw
429
429
  const data = encodeData(type, { lamports })
@@ -443,12 +443,12 @@ export class StakeProgram {
443
443
  programId: this.programId,
444
444
  data,
445
445
  })
446
- }
446
+ },
447
447
 
448
448
  /**
449
449
  * Generate a Transaction that deactivates Stake tokens.
450
450
  */
451
- static deactivate(params) {
451
+ deactivate(params) {
452
452
  const { stakePubkey, authorizedPubkey } = params
453
453
  const type = STAKE_INSTRUCTION_LAYOUTS.Deactivate
454
454
  const data = encodeData(type)
@@ -462,5 +462,5 @@ export class StakeProgram {
462
462
  programId: this.programId,
463
463
  data,
464
464
  })
465
- }
465
+ },
466
466
  }