@ignitionfi/fogo-stake-pool 1.0.3 → 1.1.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.
@@ -1,6 +1,15 @@
1
1
  import * as BufferLayout from '@solana/buffer-layout';
2
2
  import { PublicKey, TransactionInstruction } from '@solana/web3.js';
3
+ import BN from 'bn.js';
3
4
  import { InstructionType } from './utils';
5
+ /**
6
+ * Type for amounts that can be converted to BN.
7
+ * Accepts number, bigint, BN, or string representations.
8
+ *
9
+ * IMPORTANT: For values > 9,007,199,254,740,991 (Number.MAX_SAFE_INTEGER),
10
+ * you MUST use bigint, BN, or string to avoid precision loss.
11
+ */
12
+ export type AmountInput = number | bigint | BN | string;
4
13
  /**
5
14
  * An enumeration of valid StakePoolInstructionType's
6
15
  */
@@ -60,8 +69,8 @@ export type DecreaseValidatorStakeParams = {
60
69
  validatorList: PublicKey;
61
70
  validatorStake: PublicKey;
62
71
  transientStake: PublicKey;
63
- lamports: number;
64
- transientStakeSeed: number;
72
+ lamports: AmountInput;
73
+ transientStakeSeed: AmountInput;
65
74
  };
66
75
  export interface DecreaseValidatorStakeWithReserveParams extends DecreaseValidatorStakeParams {
67
76
  reserveStake: PublicKey;
@@ -69,7 +78,7 @@ export interface DecreaseValidatorStakeWithReserveParams extends DecreaseValidat
69
78
  export interface DecreaseAdditionalValidatorStakeParams extends DecreaseValidatorStakeParams {
70
79
  reserveStake: PublicKey;
71
80
  ephemeralStake: PublicKey;
72
- ephemeralStakeSeed: number;
81
+ ephemeralStakeSeed: AmountInput;
73
82
  }
74
83
  /**
75
84
  * (Staker only) Increase stake on a validator from the reserve account.
@@ -84,12 +93,12 @@ export type IncreaseValidatorStakeParams = {
84
93
  transientStake: PublicKey;
85
94
  validatorStake: PublicKey;
86
95
  validatorVote: PublicKey;
87
- lamports: number;
88
- transientStakeSeed: number;
96
+ lamports: AmountInput;
97
+ transientStakeSeed: AmountInput;
89
98
  };
90
99
  export interface IncreaseAdditionalValidatorStakeParams extends IncreaseValidatorStakeParams {
91
100
  ephemeralStake: PublicKey;
92
- ephemeralStakeSeed: number;
101
+ ephemeralStakeSeed: AmountInput;
93
102
  }
94
103
  /**
95
104
  * Deposits a stake account into the pool in exchange for pool tokens
@@ -123,7 +132,7 @@ export type WithdrawStakeParams = {
123
132
  sourcePoolAccount: PublicKey;
124
133
  managerFeeAccount: PublicKey;
125
134
  poolMint: PublicKey;
126
- poolTokens: number;
135
+ poolTokens: AmountInput;
127
136
  };
128
137
  /**
129
138
  * Withdraw sol instruction params
@@ -139,7 +148,7 @@ export type WithdrawSolParams = {
139
148
  solWithdrawAuthority?: PublicKey | undefined;
140
149
  managerFeeAccount: PublicKey;
141
150
  poolMint: PublicKey;
142
- poolTokens: number;
151
+ poolTokens: AmountInput;
143
152
  };
144
153
  /**
145
154
  * Withdraw WSOL with session instruction params
@@ -158,8 +167,8 @@ export type WithdrawWsolWithSessionParams = {
158
167
  wsolMint: PublicKey;
159
168
  programSigner: PublicKey;
160
169
  userWallet: PublicKey;
161
- poolTokensIn: number;
162
- minimumLamportsOut: number;
170
+ poolTokensIn: AmountInput;
171
+ minimumLamportsOut: AmountInput;
163
172
  solWithdrawAuthority?: PublicKey;
164
173
  };
165
174
  export type WithdrawStakeWithSessionParams = {
@@ -180,10 +189,10 @@ export type WithdrawStakeWithSessionParams = {
180
189
  programSigner: PublicKey;
181
190
  /** Reserve stake account for rent funding */
182
191
  reserveStake: PublicKey;
183
- poolTokensIn: number;
184
- minimumLamportsOut: number;
192
+ poolTokensIn: AmountInput;
193
+ minimumLamportsOut: AmountInput;
185
194
  /** Seed used to derive the user stake PDA */
186
- userStakeSeed: number;
195
+ userStakeSeed: AmountInput;
187
196
  };
188
197
  export type WithdrawFromStakeAccountWithSessionParams = {
189
198
  programId: PublicKey;
@@ -194,9 +203,9 @@ export type WithdrawFromStakeAccountWithSessionParams = {
194
203
  /** The session signer (user or session) */
195
204
  sessionSigner: PublicKey;
196
205
  /** Seed used to derive the user stake PDA */
197
- userStakeSeed: number;
198
- /** Lamports to withdraw (use Number.MAX_SAFE_INTEGER for full withdrawal) */
199
- lamports: number;
206
+ userStakeSeed: AmountInput;
207
+ /** Lamports to withdraw (use BigInt(Number.MAX_SAFE_INTEGER) for full withdrawal) */
208
+ lamports: AmountInput;
200
209
  };
201
210
  /**
202
211
  * Deposit SOL directly into the pool's reserve account. The output is a "pool" token
@@ -213,7 +222,7 @@ export type DepositSolParams = {
213
222
  managerFeeAccount: PublicKey;
214
223
  referralPoolAccount: PublicKey;
215
224
  poolMint: PublicKey;
216
- lamports: number;
225
+ lamports: AmountInput;
217
226
  };
218
227
  export type CreateTokenMetadataParams = {
219
228
  programId?: PublicKey | undefined;
@@ -325,8 +334,8 @@ export declare class StakePoolInstruction {
325
334
  tokenProgramId: PublicKey;
326
335
  programId: PublicKey;
327
336
  userWallet: PublicKey;
328
- lamportsIn: number;
329
- minimumPoolTokensOut: number;
337
+ lamportsIn: AmountInput;
338
+ minimumPoolTokensOut: AmountInput;
330
339
  payer?: PublicKey;
331
340
  }): TransactionInstruction;
332
341
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ignitionfi/fogo-stake-pool",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Fogo Stake Pool SDK",
5
5
  "contributors": [
6
6
  "Anza Maintainers <maintainers@anza.xyz>",
package/src/codecs.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as BufferLayout from '@solana/buffer-layout'
1
2
  import { PublicKey } from '@solana/web3.js'
2
3
  import BN from 'bn.js'
3
4
  import { blob, Layout as LayoutCls, offset, seq, struct, u8, u32 } from 'buffer-layout'
@@ -15,18 +16,22 @@ export interface Layout<T> {
15
16
  replicate: (name: string) => this
16
17
  }
17
18
 
18
- class BNLayout extends LayoutCls<BN> {
19
- blob: Layout<Buffer>
19
+ /**
20
+ * BN-based layout for data decoding using buffer-layout.
21
+ * Used for decoding on-chain account data (StakePool, ValidatorList, etc.)
22
+ */
23
+ class BNDataLayout extends LayoutCls<BN> {
24
+ blobLayout: Layout<Buffer>
20
25
  signed: boolean
21
26
 
22
27
  constructor(span: number, signed: boolean, property?: string) {
23
28
  super(span, property)
24
- this.blob = blob(span)
29
+ this.blobLayout = blob(span)
25
30
  this.signed = signed
26
31
  }
27
32
 
28
33
  decode(b: Buffer, offset = 0) {
29
- const num = new BN(this.blob.decode(b, offset), 10, 'le')
34
+ const num = new BN(this.blobLayout.decode(b, offset), 10, 'le')
30
35
  if (this.signed) {
31
36
  return num.fromTwos(this.span * 8).clone()
32
37
  }
@@ -37,12 +42,60 @@ class BNLayout extends LayoutCls<BN> {
37
42
  if (this.signed) {
38
43
  src = src.toTwos(this.span * 8)
39
44
  }
40
- return this.blob.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset)
45
+ return this.blobLayout.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset)
41
46
  }
42
47
  }
43
48
 
49
+ /**
50
+ * Creates a u64 layout for data decoding (account layouts).
51
+ * Used in StakePoolLayout, ValidatorListLayout, etc.
52
+ */
44
53
  export function u64(property?: string): Layout<BN> {
45
- return new BNLayout(8, false, property)
54
+ return new BNDataLayout(8, false, property)
55
+ }
56
+
57
+ /**
58
+ * BN-based layout for 64-bit unsigned integers using @solana/buffer-layout.
59
+ * Used for encoding instruction data with support for values > MAX_SAFE_INTEGER.
60
+ */
61
+ class BNInstructionLayout extends BufferLayout.Layout<BN> {
62
+ blobLayout: BufferLayout.Blob
63
+ signed: boolean
64
+
65
+ constructor(span: number, signed: boolean, property?: string) {
66
+ super(span, property)
67
+ this.blobLayout = BufferLayout.blob(span)
68
+ this.signed = signed
69
+ }
70
+
71
+ decode(b: Uint8Array, offset = 0): BN {
72
+ const num = new BN(this.blobLayout.decode(b, offset), 10, 'le')
73
+ if (this.signed) {
74
+ return num.fromTwos(this.span * 8).clone()
75
+ }
76
+ return num
77
+ }
78
+
79
+ encode(src: BN, b: Uint8Array, offset = 0): number {
80
+ if (this.signed) {
81
+ src = src.toTwos(this.span * 8)
82
+ }
83
+ return this.blobLayout.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset)
84
+ }
85
+
86
+ getSpan(_b?: Uint8Array, _offset?: number): number {
87
+ return this.span
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Creates a u64 layout for instruction encoding.
93
+ * Properly handles BN values larger than Number.MAX_SAFE_INTEGER.
94
+ * Compatible with @solana/buffer-layout.struct().
95
+ */
96
+ // eslint-disable-next-line ts/no-explicit-any
97
+ export function u64Instruction(property?: string): any {
98
+ return new BNInstructionLayout(8, false, property)
46
99
  }
47
100
 
48
101
  class WrappedLayout<T, U> extends LayoutCls<U> {
package/src/index.ts CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  MINIMUM_ACTIVE_STAKE,
25
25
  STAKE_POOL_PROGRAM_ID,
26
26
  } from './constants'
27
- import { StakePoolInstruction } from './instructions'
27
+ import { AmountInput, StakePoolInstruction } from './instructions'
28
28
  import {
29
29
  StakeAccount,
30
30
  StakePool,
@@ -304,8 +304,8 @@ export async function depositWsolWithSession(
304
304
  stakePoolAddress: PublicKey,
305
305
  signerOrSession: PublicKey,
306
306
  userPubkey: PublicKey,
307
- lamports: number,
308
- minimumPoolTokensOut: number = 0,
307
+ lamports: AmountInput,
308
+ minimumPoolTokensOut: AmountInput = 0,
309
309
  destinationTokenAccount?: PublicKey,
310
310
  referrerTokenAccount?: PublicKey,
311
311
  depositAuthority?: PublicKey,
@@ -324,13 +324,22 @@ export async function depositWsolWithSession(
324
324
  'confirmed',
325
325
  )
326
326
  const wsolBalance = tokenAccountInfo
327
- ? parseInt(tokenAccountInfo.value.amount)
328
- : 0
329
-
330
- if (wsolBalance < lamports) {
327
+ ? BigInt(tokenAccountInfo.value.amount)
328
+ : BigInt(0)
329
+
330
+ // Convert lamports to BigInt for comparison
331
+ const lamportsBigInt = typeof lamports === 'bigint'
332
+ ? lamports
333
+ : typeof lamports === 'string'
334
+ ? BigInt(lamports)
335
+ : BN.isBN(lamports)
336
+ ? BigInt(lamports.toString())
337
+ : BigInt(lamports)
338
+
339
+ if (wsolBalance < lamportsBigInt) {
331
340
  throw new Error(
332
341
  `Not enough WSOL to deposit into pool. Maximum deposit amount is ${lamportsToSol(
333
- wsolBalance,
342
+ Number(wsolBalance),
334
343
  )} WSOL.`,
335
344
  )
336
345
  }
@@ -402,13 +411,23 @@ export async function depositSol(
402
411
  connection: Connection,
403
412
  stakePoolAddress: PublicKey,
404
413
  from: PublicKey,
405
- lamports: number,
414
+ lamports: AmountInput,
406
415
  destinationTokenAccount?: PublicKey,
407
416
  referrerTokenAccount?: PublicKey,
408
417
  depositAuthority?: PublicKey,
409
418
  ) {
410
419
  const fromBalance = await connection.getBalance(from, 'confirmed')
411
- if (fromBalance < lamports) {
420
+
421
+ // Convert lamports to BigInt for comparison
422
+ const lamportsBigInt = typeof lamports === 'bigint'
423
+ ? lamports
424
+ : typeof lamports === 'string'
425
+ ? BigInt(lamports)
426
+ : BN.isBN(lamports)
427
+ ? BigInt(lamports.toString())
428
+ : BigInt(lamports)
429
+
430
+ if (BigInt(fromBalance) < lamportsBigInt) {
412
431
  throw new Error(
413
432
  `Not enough SOL to deposit into pool. Maximum deposit amount is ${lamportsToSol(
414
433
  fromBalance,
@@ -433,7 +452,7 @@ export async function depositSol(
433
452
  SystemProgram.transfer({
434
453
  fromPubkey: from,
435
454
  toPubkey: userSolTransfer.publicKey,
436
- lamports,
455
+ lamports: lamportsBigInt,
437
456
  }),
438
457
  )
439
458
 
@@ -1363,7 +1382,7 @@ export async function increaseValidatorStake(
1363
1382
  connection: Connection,
1364
1383
  stakePoolAddress: PublicKey,
1365
1384
  validatorVote: PublicKey,
1366
- lamports: number,
1385
+ lamports: AmountInput,
1367
1386
  ephemeralStakeSeed?: number,
1368
1387
  ) {
1369
1388
  const stakePool = await getStakePoolAccount(connection, stakePoolAddress)
@@ -1461,7 +1480,7 @@ export async function decreaseValidatorStake(
1461
1480
  connection: Connection,
1462
1481
  stakePoolAddress: PublicKey,
1463
1482
  validatorVote: PublicKey,
1464
- lamports: number,
1483
+ lamports: AmountInput,
1465
1484
  ephemeralStakeSeed?: number,
1466
1485
  ) {
1467
1486
  const stakePool = await getStakePoolAccount(connection, stakePoolAddress)