@ignitionfi/fogo-stake-pool 1.0.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/LICENSE +176 -0
- package/dist/codecs.d.ts +15 -0
- package/dist/constants.d.ts +13 -0
- package/dist/index.browser.cjs.js +2898 -0
- package/dist/index.browser.cjs.js.map +1 -0
- package/dist/index.browser.esm.js +2843 -0
- package/dist/index.browser.esm.js.map +1 -0
- package/dist/index.cjs.js +2898 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +268 -0
- package/dist/index.esm.js +2843 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.iife.js +24083 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.iife.min.js +19 -0
- package/dist/index.iife.min.js.map +1 -0
- package/dist/instructions.d.ts +381 -0
- package/dist/layouts.d.ts +318 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/instruction.d.ts +21 -0
- package/dist/utils/math.d.ts +3 -0
- package/dist/utils/program-address.d.ts +31 -0
- package/dist/utils/stake.d.ts +29 -0
- package/package.json +90 -0
- package/src/codecs.ts +159 -0
- package/src/constants.ts +30 -0
- package/src/index.ts +1823 -0
- package/src/instructions.ts +1439 -0
- package/src/layouts.ts +248 -0
- package/src/types/buffer-layout.d.ts +29 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/instruction.ts +46 -0
- package/src/utils/math.ts +29 -0
- package/src/utils/program-address.ts +125 -0
- package/src/utils/stake.ts +233 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import * as BufferLayout from '@solana/buffer-layout';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export type InstructionType = {
|
|
7
|
+
/** The Instruction index (from solana upstream program) */
|
|
8
|
+
index: number;
|
|
9
|
+
/** The BufferLayout to use to build data */
|
|
10
|
+
layout: BufferLayout.Layout<any>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Populate a buffer of instruction data using an InstructionType
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function encodeData(type: InstructionType, fields?: any): Buffer;
|
|
17
|
+
/**
|
|
18
|
+
* Decode instruction data buffer using an InstructionType
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare function decodeData(type: InstructionType, buffer: Buffer): any;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import BN from 'bn.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generates the wSOL transient program address for the stake pool
|
|
5
|
+
*/
|
|
6
|
+
export declare function findWsolTransientProgramAddress(programId: PublicKey, userPubkey: PublicKey): PublicKey;
|
|
7
|
+
/**
|
|
8
|
+
* Generates the withdraw authority program address for the stake pool
|
|
9
|
+
*/
|
|
10
|
+
export declare function findWithdrawAuthorityProgramAddress(programId: PublicKey, stakePoolAddress: PublicKey): Promise<PublicKey>;
|
|
11
|
+
/**
|
|
12
|
+
* Generates the stake program address for a validator's vote account
|
|
13
|
+
*/
|
|
14
|
+
export declare function findStakeProgramAddress(programId: PublicKey, voteAccountAddress: PublicKey, stakePoolAddress: PublicKey, seed?: number): Promise<PublicKey>;
|
|
15
|
+
/**
|
|
16
|
+
* Generates the stake program address for a validator's vote account
|
|
17
|
+
*/
|
|
18
|
+
export declare function findTransientStakeProgramAddress(programId: PublicKey, voteAccountAddress: PublicKey, stakePoolAddress: PublicKey, seed: BN): Promise<PublicKey>;
|
|
19
|
+
/**
|
|
20
|
+
* Generates the ephemeral program address for stake pool redelegation
|
|
21
|
+
*/
|
|
22
|
+
export declare function findEphemeralStakeProgramAddress(programId: PublicKey, stakePoolAddress: PublicKey, seed: BN): Promise<PublicKey>;
|
|
23
|
+
/**
|
|
24
|
+
* Generates the metadata program address for the stake pool
|
|
25
|
+
*/
|
|
26
|
+
export declare function findMetadataAddress(stakePoolMintAddress: PublicKey): PublicKey;
|
|
27
|
+
/**
|
|
28
|
+
* Generates the user stake account PDA for session-based withdrawals.
|
|
29
|
+
* The PDA is derived from the user's wallet and a unique seed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function findUserStakeProgramAddress(programId: PublicKey, userWallet: PublicKey, seed: BN | number): PublicKey;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Connection, Keypair, PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
2
|
+
import BN from 'bn.js';
|
|
3
|
+
import { WithdrawAccount } from '../index';
|
|
4
|
+
import { StakePool, ValidatorList } from '../layouts';
|
|
5
|
+
export declare function getValidatorListAccount(connection: Connection, pubkey: PublicKey): Promise<{
|
|
6
|
+
pubkey: PublicKey;
|
|
7
|
+
account: {
|
|
8
|
+
data: ValidatorList;
|
|
9
|
+
executable: boolean;
|
|
10
|
+
lamports: number;
|
|
11
|
+
owner: PublicKey;
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
export interface ValidatorAccount {
|
|
15
|
+
type: 'preferred' | 'active' | 'transient' | 'reserve';
|
|
16
|
+
voteAddress?: PublicKey | undefined;
|
|
17
|
+
stakeAddress: PublicKey;
|
|
18
|
+
lamports: BN;
|
|
19
|
+
}
|
|
20
|
+
export declare function prepareWithdrawAccounts(connection: Connection, stakePool: StakePool, stakePoolAddress: PublicKey, amount: BN, compareFn?: (a: ValidatorAccount, b: ValidatorAccount) => number, skipFee?: boolean): Promise<WithdrawAccount[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Calculate the pool tokens that should be minted for a deposit of `stakeLamports`
|
|
23
|
+
*/
|
|
24
|
+
export declare function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: BN): BN;
|
|
25
|
+
/**
|
|
26
|
+
* Calculate lamports amount on withdrawal
|
|
27
|
+
*/
|
|
28
|
+
export declare function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: BN): BN;
|
|
29
|
+
export declare function newStakeAccount(feePayer: PublicKey, instructions: TransactionInstruction[], lamports: number): Keypair;
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ignitionfi/fogo-stake-pool",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fogo Stake Pool SDK",
|
|
5
|
+
"contributors": [
|
|
6
|
+
"Anza Maintainers <maintainers@anza.xyz>",
|
|
7
|
+
"Lieu Zheng Hong",
|
|
8
|
+
"mFactory Team (https://mfactory.ch/)",
|
|
9
|
+
"SolBlaze <contact@solblaze.org> (https://solblaze.org/)",
|
|
10
|
+
"Ignition Team (https://ignitionfi.xyz/)"
|
|
11
|
+
],
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"homepage": "https://ignitionfi.xyz",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/tempest-finance/fogo-stake-pool"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"browser": {
|
|
23
|
+
"./dist/index.cjs.js": "./dist/index.browser.cjs.js",
|
|
24
|
+
"./dist/index.esm.js": "./dist/index.browser.esm.js"
|
|
25
|
+
},
|
|
26
|
+
"main": "dist/index.cjs.js",
|
|
27
|
+
"module": "dist/index.esm.js",
|
|
28
|
+
"types": "dist/index.d.ts",
|
|
29
|
+
"browserslist": [
|
|
30
|
+
"defaults",
|
|
31
|
+
"not IE 11",
|
|
32
|
+
"maintained node versions"
|
|
33
|
+
],
|
|
34
|
+
"files": [
|
|
35
|
+
"/dist",
|
|
36
|
+
"/src"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@solana/buffer-layout": "^4.0.1",
|
|
40
|
+
"@solana/spl-token": "0.4.13",
|
|
41
|
+
"@solana/web3.js": "^1.95.5",
|
|
42
|
+
"bn.js": "^5.2.0",
|
|
43
|
+
"buffer": "^6.0.3",
|
|
44
|
+
"buffer-layout": "^1.2.2",
|
|
45
|
+
"superstruct": "^2.0.2"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@rollup/plugin-alias": "^5.1.1",
|
|
49
|
+
"@rollup/plugin-commonjs": "^28.0.1",
|
|
50
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
51
|
+
"@rollup/plugin-multi-entry": "^6.0.0",
|
|
52
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
53
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
54
|
+
"@rollup/plugin-typescript": "^12.1.1",
|
|
55
|
+
"@types/bn.js": "^5.1.6",
|
|
56
|
+
"@types/jest": "^30.0.0",
|
|
57
|
+
"@types/node": "^24.0.0",
|
|
58
|
+
"@types/node-fetch": "^2.6.12",
|
|
59
|
+
"cross-env": "^10.0.0",
|
|
60
|
+
"jest": "^30.0.3",
|
|
61
|
+
"rimraf": "^6.0.1",
|
|
62
|
+
"rollup": "^4.28.0",
|
|
63
|
+
"rollup-plugin-dts": "^6.1.1",
|
|
64
|
+
"ts-jest": "^29.2.5"
|
|
65
|
+
},
|
|
66
|
+
"jest": {
|
|
67
|
+
"moduleFileExtensions": [
|
|
68
|
+
"js",
|
|
69
|
+
"json",
|
|
70
|
+
"ts"
|
|
71
|
+
],
|
|
72
|
+
"rootDir": ".",
|
|
73
|
+
"transform": {
|
|
74
|
+
"^.+\\.(t|j)s$": "ts-jest"
|
|
75
|
+
},
|
|
76
|
+
"testRegex": ".*\\.test\\.ts$",
|
|
77
|
+
"testEnvironment": "node"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsc && cross-env NODE_ENV=production rollup -c",
|
|
81
|
+
"dev": "tsc && cross-env NODE_ENV=production rollup -c -w",
|
|
82
|
+
"build:program": "cargo build-sbf --manifest-path=../program/Cargo.toml",
|
|
83
|
+
"format": "prettier --check src test",
|
|
84
|
+
"format:fix": "prettier --write src test",
|
|
85
|
+
"lint": "eslint --max-warnings 0 .",
|
|
86
|
+
"lint:fix": "eslint . --fix",
|
|
87
|
+
"test": "jest",
|
|
88
|
+
"clean": "rimraf ./dist"
|
|
89
|
+
}
|
|
90
|
+
}
|
package/src/codecs.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js'
|
|
2
|
+
import BN from 'bn.js'
|
|
3
|
+
import { blob, Layout as LayoutCls, offset, seq, struct, u8, u32 } from 'buffer-layout'
|
|
4
|
+
|
|
5
|
+
export interface Layout<T> {
|
|
6
|
+
span: number
|
|
7
|
+
property?: string
|
|
8
|
+
|
|
9
|
+
decode: (b: Buffer, offset?: number) => T
|
|
10
|
+
|
|
11
|
+
encode: (src: T, b: Buffer, offset?: number) => number
|
|
12
|
+
|
|
13
|
+
getSpan: (b: Buffer, offset?: number) => number
|
|
14
|
+
|
|
15
|
+
replicate: (name: string) => this
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class BNLayout extends LayoutCls<BN> {
|
|
19
|
+
blob: Layout<Buffer>
|
|
20
|
+
signed: boolean
|
|
21
|
+
|
|
22
|
+
constructor(span: number, signed: boolean, property?: string) {
|
|
23
|
+
super(span, property)
|
|
24
|
+
this.blob = blob(span)
|
|
25
|
+
this.signed = signed
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
decode(b: Buffer, offset = 0) {
|
|
29
|
+
const num = new BN(this.blob.decode(b, offset), 10, 'le')
|
|
30
|
+
if (this.signed) {
|
|
31
|
+
return num.fromTwos(this.span * 8).clone()
|
|
32
|
+
}
|
|
33
|
+
return num
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
encode(src: BN, b: Buffer, offset = 0) {
|
|
37
|
+
if (this.signed) {
|
|
38
|
+
src = src.toTwos(this.span * 8)
|
|
39
|
+
}
|
|
40
|
+
return this.blob.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function u64(property?: string): Layout<BN> {
|
|
45
|
+
return new BNLayout(8, false, property)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
class WrappedLayout<T, U> extends LayoutCls<U> {
|
|
49
|
+
layout: Layout<T>
|
|
50
|
+
decoder: (data: T) => U
|
|
51
|
+
encoder: (src: U) => T
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
layout: Layout<T>,
|
|
55
|
+
decoder: (data: T) => U,
|
|
56
|
+
encoder: (src: U) => T,
|
|
57
|
+
property?: string,
|
|
58
|
+
) {
|
|
59
|
+
super(layout.span, property)
|
|
60
|
+
this.layout = layout
|
|
61
|
+
this.decoder = decoder
|
|
62
|
+
this.encoder = encoder
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
decode(b: Buffer, offset?: number): U {
|
|
66
|
+
return this.decoder(this.layout.decode(b, offset))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
encode(src: U, b: Buffer, offset?: number): number {
|
|
70
|
+
return this.layout.encode(this.encoder(src), b, offset)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getSpan(b: Buffer, offset?: number): number {
|
|
74
|
+
return this.layout.getSpan(b, offset)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function publicKey(property?: string): Layout<PublicKey> {
|
|
79
|
+
return new WrappedLayout(
|
|
80
|
+
blob(32),
|
|
81
|
+
(b: Buffer) => new PublicKey(b),
|
|
82
|
+
(key: PublicKey) => key.toBuffer(),
|
|
83
|
+
property,
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class OptionLayout<T> extends LayoutCls<T | null> {
|
|
88
|
+
layout: Layout<T>
|
|
89
|
+
discriminator: Layout<number>
|
|
90
|
+
|
|
91
|
+
constructor(layout: Layout<T>, property?: string) {
|
|
92
|
+
super(-1, property)
|
|
93
|
+
this.layout = layout
|
|
94
|
+
this.discriminator = u8()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
encode(src: T | null, b: Buffer, offset = 0): number {
|
|
98
|
+
if (src === null || src === undefined) {
|
|
99
|
+
return this.discriminator.encode(0, b, offset)
|
|
100
|
+
}
|
|
101
|
+
this.discriminator.encode(1, b, offset)
|
|
102
|
+
return this.layout.encode(src, b, offset + 1) + 1
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
decode(b: Buffer, offset = 0): T | null {
|
|
106
|
+
const discriminator = this.discriminator.decode(b, offset)
|
|
107
|
+
if (discriminator === 0) {
|
|
108
|
+
return null
|
|
109
|
+
} else if (discriminator === 1) {
|
|
110
|
+
return this.layout.decode(b, offset + 1)
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`Invalid option ${this.property}`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getSpan(b: Buffer, offset = 0): number {
|
|
116
|
+
const discriminator = this.discriminator.decode(b, offset)
|
|
117
|
+
if (discriminator === 0) {
|
|
118
|
+
return 1
|
|
119
|
+
} else if (discriminator === 1) {
|
|
120
|
+
return this.layout.getSpan(b, offset + 1) + 1
|
|
121
|
+
}
|
|
122
|
+
throw new Error(`Invalid option ${this.property}`)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function option<T>(layout: Layout<T>, property?: string): Layout<T | null> {
|
|
127
|
+
return new OptionLayout<T>(layout, property)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function bool(property?: string): Layout<boolean> {
|
|
131
|
+
return new WrappedLayout(u8(), decodeBool, encodeBool, property)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function decodeBool(value: number): boolean {
|
|
135
|
+
if (value === 0) {
|
|
136
|
+
return false
|
|
137
|
+
} else if (value === 1) {
|
|
138
|
+
return true
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`Invalid bool: ${value}`)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function encodeBool(value: boolean): number {
|
|
144
|
+
return value ? 1 : 0
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function vec<T>(elementLayout: Layout<T>, property?: string): Layout<T[]> {
|
|
148
|
+
const length = u32('length')
|
|
149
|
+
const layout: Layout<{ values: T[] }> = struct([
|
|
150
|
+
length,
|
|
151
|
+
seq(elementLayout, offset(length, -length.span), 'values'),
|
|
152
|
+
])
|
|
153
|
+
return new WrappedLayout(
|
|
154
|
+
layout,
|
|
155
|
+
({ values }) => values,
|
|
156
|
+
values => ({ values }),
|
|
157
|
+
property,
|
|
158
|
+
)
|
|
159
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer'
|
|
2
|
+
import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'
|
|
3
|
+
|
|
4
|
+
// Public key that identifies the metadata program.
|
|
5
|
+
export const METADATA_PROGRAM_ID = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s')
|
|
6
|
+
export const METADATA_MAX_NAME_LENGTH = 32
|
|
7
|
+
export const METADATA_MAX_SYMBOL_LENGTH = 10
|
|
8
|
+
export const METADATA_MAX_URI_LENGTH = 200
|
|
9
|
+
|
|
10
|
+
// Public key that identifies the SPL Stake Pool program.
|
|
11
|
+
export const STAKE_POOL_PROGRAM_ID = new PublicKey('SP1s4uFeTAX9jsXXmwyDs1gxYYf7cdDZ8qHUHVxE1yr')
|
|
12
|
+
|
|
13
|
+
// Public key that identifies the SPL Stake Pool program deployed to devnet.
|
|
14
|
+
export const DEVNET_STAKE_POOL_PROGRAM_ID = new PublicKey('DPoo15wWDqpPJJtS2MUZ49aRxqz5ZaaJCJP4z8bLuib')
|
|
15
|
+
|
|
16
|
+
// Maximum number of validators to update during UpdateValidatorListBalance.
|
|
17
|
+
export const MAX_VALIDATORS_TO_UPDATE = 4
|
|
18
|
+
|
|
19
|
+
// Seed for ephemeral stake account
|
|
20
|
+
export const EPHEMERAL_STAKE_SEED_PREFIX = Buffer.from('ephemeral')
|
|
21
|
+
|
|
22
|
+
// Seed used to derive transient stake accounts.
|
|
23
|
+
export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient')
|
|
24
|
+
|
|
25
|
+
// Seed for user stake account created during session withdrawal
|
|
26
|
+
export const USER_STAKE_SEED_PREFIX = Buffer.from('user_stake')
|
|
27
|
+
|
|
28
|
+
// Minimum amount of staked SOL required in a validator stake account to allow
|
|
29
|
+
// for merges without a mismatch on credits observed
|
|
30
|
+
export const MINIMUM_ACTIVE_STAKE = LAMPORTS_PER_SOL
|