@ignitionfi/spl-stake-pool 1.1.10
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 +12 -0
- package/dist/index.browser.cjs.js +2569 -0
- package/dist/index.browser.cjs.js.map +1 -0
- package/dist/index.browser.esm.js +2523 -0
- package/dist/index.browser.esm.js.map +1 -0
- package/dist/index.cjs.js +2569 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +195 -0
- package/dist/index.esm.js +2523 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.iife.js +23754 -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 +329 -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 +26 -0
- package/dist/utils/stake.d.ts +29 -0
- package/package.json +90 -0
- package/src/codecs.ts +159 -0
- package/src/constants.ts +29 -0
- package/src/index.ts +1523 -0
- package/src/instructions.ts +1293 -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 +103 -0
- package/src/utils/stake.ts +230 -0
|
@@ -0,0 +1,26 @@
|
|
|
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;
|
|
@@ -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/spl-stake-pool",
|
|
3
|
+
"version": "1.1.10",
|
|
4
|
+
"description": "Ignition Stake Pool SDK for FOGO",
|
|
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
|
+
],
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"homepage": "https://solana.com",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/solana-labs/solana-program-library"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"browser": {
|
|
22
|
+
"./dist/index.cjs.js": "./dist/index.browser.cjs.js",
|
|
23
|
+
"./dist/index.esm.js": "./dist/index.browser.esm.js"
|
|
24
|
+
},
|
|
25
|
+
"main": "dist/index.cjs.js",
|
|
26
|
+
"module": "dist/index.esm.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"browserslist": [
|
|
29
|
+
"defaults",
|
|
30
|
+
"not IE 11",
|
|
31
|
+
"maintained node versions"
|
|
32
|
+
],
|
|
33
|
+
"files": [
|
|
34
|
+
"/dist",
|
|
35
|
+
"/src"
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@solana/buffer-layout": "^4.0.1",
|
|
39
|
+
"@solana/spl-token": "0.4.13",
|
|
40
|
+
"@solana/web3.js": "^1.95.5",
|
|
41
|
+
"bn.js": "^5.2.0",
|
|
42
|
+
"buffer": "^6.0.3",
|
|
43
|
+
"buffer-layout": "^1.2.2",
|
|
44
|
+
"superstruct": "^2.0.2"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@rollup/plugin-alias": "^5.1.1",
|
|
48
|
+
"@rollup/plugin-commonjs": "^28.0.1",
|
|
49
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
50
|
+
"@rollup/plugin-multi-entry": "^6.0.0",
|
|
51
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
52
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
53
|
+
"@rollup/plugin-typescript": "^12.1.1",
|
|
54
|
+
"@types/bn.js": "^5.1.6",
|
|
55
|
+
"@types/jest": "^30.0.0",
|
|
56
|
+
"@types/node": "^24.0.0",
|
|
57
|
+
"@types/node-fetch": "^2.6.12",
|
|
58
|
+
"cross-env": "^10.0.0",
|
|
59
|
+
"jest": "^30.0.3",
|
|
60
|
+
"rimraf": "^6.0.1",
|
|
61
|
+
"rollup": "^4.28.0",
|
|
62
|
+
"rollup-plugin-dts": "^6.1.1",
|
|
63
|
+
"ts-jest": "^29.2.5"
|
|
64
|
+
},
|
|
65
|
+
"jest": {
|
|
66
|
+
"moduleFileExtensions": [
|
|
67
|
+
"js",
|
|
68
|
+
"json",
|
|
69
|
+
"ts"
|
|
70
|
+
],
|
|
71
|
+
"rootDir": ".",
|
|
72
|
+
"transform": {
|
|
73
|
+
"^.+\\.(t|j)s$": "ts-jest"
|
|
74
|
+
},
|
|
75
|
+
"testRegex": ".*\\.test\\.ts$",
|
|
76
|
+
"testEnvironment": "node"
|
|
77
|
+
},
|
|
78
|
+
"scripts": {
|
|
79
|
+
"build": "tsc && cross-env NODE_ENV=production rollup -c",
|
|
80
|
+
"dev": "tsc && cross-env NODE_ENV=production rollup -c -w",
|
|
81
|
+
"build:program": "cargo build-sbf --manifest-path=../program/Cargo.toml",
|
|
82
|
+
"format": "prettier --check src test",
|
|
83
|
+
"format:fix": "prettier --write src test",
|
|
84
|
+
"lint": "eslint --max-warnings 0 .",
|
|
85
|
+
"lint:fix": "eslint . --fix",
|
|
86
|
+
"test": "jest",
|
|
87
|
+
"clean": "rimraf ./dist",
|
|
88
|
+
"postinstall": "npm run build"
|
|
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,29 @@
|
|
|
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(
|
|
15
|
+
'DPoo15wWDqpPJJtS2MUZ49aRxqz5ZaaJCJP4z8bLuib',
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
// Maximum number of validators to update during UpdateValidatorListBalance.
|
|
19
|
+
export const MAX_VALIDATORS_TO_UPDATE = 4
|
|
20
|
+
|
|
21
|
+
// Seed for ephemeral stake account
|
|
22
|
+
export const EPHEMERAL_STAKE_SEED_PREFIX = Buffer.from('ephemeral')
|
|
23
|
+
|
|
24
|
+
// Seed used to derive transient stake accounts.
|
|
25
|
+
export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient')
|
|
26
|
+
|
|
27
|
+
// Minimum amount of staked SOL required in a validator stake account to allow
|
|
28
|
+
// for merges without a mismatch on credits observed
|
|
29
|
+
export const MINIMUM_ACTIVE_STAKE = LAMPORTS_PER_SOL
|