multistake 0.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.
- package/README.md +50 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/multistake.json +790 -0
- package/dist/sdk.d.ts +88 -0
- package/dist/sdk.js +247 -0
- package/dist/types/multistake.d.ts +796 -0
- package/dist/types/multistake.js +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.js +1 -0
- package/package.json +39 -0
package/dist/sdk.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Program, AnchorProvider, BN } from "@coral-xyz/anchor";
|
|
2
|
+
import { PublicKey, Keypair } from "@solana/web3.js";
|
|
3
|
+
import { Multistake } from "./types/multistake";
|
|
4
|
+
import { PoolConfig, PoolInfo, TokenInfo, ModifyWeightParams } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* AnySwap SDK - 单币质押系统
|
|
7
|
+
*/
|
|
8
|
+
export declare class MultiStakeSDK {
|
|
9
|
+
private program;
|
|
10
|
+
private provider;
|
|
11
|
+
constructor(program: Program<Multistake>, provider?: AnchorProvider);
|
|
12
|
+
/**
|
|
13
|
+
* 使用内置 IDL 创建 SDK 实例
|
|
14
|
+
*/
|
|
15
|
+
static create(provider: AnchorProvider): MultiStakeSDK;
|
|
16
|
+
/**
|
|
17
|
+
* 获取 Program 实例
|
|
18
|
+
*/
|
|
19
|
+
getProgram(): Program<Multistake>;
|
|
20
|
+
/**
|
|
21
|
+
* 获取 Provider 实例
|
|
22
|
+
*/
|
|
23
|
+
getProvider(): AnchorProvider;
|
|
24
|
+
/**
|
|
25
|
+
* 派生 Pool Authority PDA
|
|
26
|
+
*/
|
|
27
|
+
derivePoolAuthority(pool: PublicKey): [PublicKey, number];
|
|
28
|
+
/**
|
|
29
|
+
* 派生 Pool Vault PDA
|
|
30
|
+
*/
|
|
31
|
+
derivePoolVault(pool: PublicKey): [PublicKey, number];
|
|
32
|
+
/**
|
|
33
|
+
* 创建 Pool
|
|
34
|
+
* @param mainTokenMint 主币 mint 地址
|
|
35
|
+
* @param admin Pool 管理员
|
|
36
|
+
* @param payer 支付账户
|
|
37
|
+
* @param config Pool 配置
|
|
38
|
+
* @returns Pool 公钥和交易签名
|
|
39
|
+
*/
|
|
40
|
+
createPool(mainTokenMint: PublicKey, config?: PoolConfig): Promise<{
|
|
41
|
+
pool: PublicKey;
|
|
42
|
+
signature: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* 添加质押类型到 Pool
|
|
46
|
+
* @param pool Pool 公钥
|
|
47
|
+
* @returns LP mint 公钥和交易签名
|
|
48
|
+
*/
|
|
49
|
+
addTokenToPool(pool: PublicKey): Promise<{
|
|
50
|
+
lpMint: PublicKey;
|
|
51
|
+
signature: string;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* 从 Pool 移除质押类型
|
|
55
|
+
* @param pool Pool 公钥
|
|
56
|
+
* @param lpMint LP mint 公钥
|
|
57
|
+
* @param admin 管理员
|
|
58
|
+
* @returns 交易签名
|
|
59
|
+
*/
|
|
60
|
+
removeTokenFromPool(pool: PublicKey, lpMint: PublicKey, admin: Keypair): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* 修改 Token 权重
|
|
63
|
+
* @param pool Pool 公钥
|
|
64
|
+
* @param params 权重参数
|
|
65
|
+
* @param admin 管理员
|
|
66
|
+
* @returns 交易签名
|
|
67
|
+
*/
|
|
68
|
+
modifyTokenWeight(pool: PublicKey, params: ModifyWeightParams, admin: Keypair): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* 质押主币,铸造 LP 凭证
|
|
71
|
+
*/
|
|
72
|
+
stake(pool: PublicKey, itemIndex: number, lpMint: PublicKey, amount: number | BN): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* 销毁 LP 凭证,赎回主币
|
|
75
|
+
*/
|
|
76
|
+
unstake(pool: PublicKey, itemIndex: number, lpMint: PublicKey, lpAmount: number | BN): Promise<string>;
|
|
77
|
+
/**
|
|
78
|
+
* 获取 Pool 信息
|
|
79
|
+
*/
|
|
80
|
+
getPoolInfo(pool: PublicKey): Promise<PoolInfo & {
|
|
81
|
+
items: TokenInfo[];
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* 获取 Pool 中所有的 LP mint
|
|
85
|
+
*/
|
|
86
|
+
getPoolLpMints(pool: PublicKey): Promise<PublicKey[]>;
|
|
87
|
+
}
|
|
88
|
+
export type { PoolInfo, TokenInfo };
|
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { Program, BN } from "@coral-xyz/anchor";
|
|
2
|
+
import { PublicKey, Keypair, SystemProgram, } from "@solana/web3.js";
|
|
3
|
+
import { getAssociatedTokenAddress, } from "@solana/spl-token";
|
|
4
|
+
import IDL from "./multistake.json";
|
|
5
|
+
/**
|
|
6
|
+
* AnySwap SDK - 单币质押系统
|
|
7
|
+
*/
|
|
8
|
+
export class MultiStakeSDK {
|
|
9
|
+
constructor(program, provider) {
|
|
10
|
+
this.program = program;
|
|
11
|
+
this.provider = provider || program.provider;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 使用内置 IDL 创建 SDK 实例
|
|
15
|
+
*/
|
|
16
|
+
static create(provider) {
|
|
17
|
+
const program = new Program(IDL, provider);
|
|
18
|
+
return new MultiStakeSDK(program, provider);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 获取 Program 实例
|
|
22
|
+
*/
|
|
23
|
+
getProgram() {
|
|
24
|
+
return this.program;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 获取 Provider 实例
|
|
28
|
+
*/
|
|
29
|
+
getProvider() {
|
|
30
|
+
return this.provider;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 派生 Pool Authority PDA
|
|
34
|
+
*/
|
|
35
|
+
derivePoolAuthority(pool) {
|
|
36
|
+
return PublicKey.findProgramAddressSync([new TextEncoder().encode("anyswap_authority"), pool.toBytes()], this.program.programId);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 派生 Pool Vault PDA
|
|
40
|
+
*/
|
|
41
|
+
derivePoolVault(pool) {
|
|
42
|
+
return PublicKey.findProgramAddressSync([new TextEncoder().encode("pool_vault"), pool.toBytes()], this.program.programId);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 创建 Pool
|
|
46
|
+
* @param mainTokenMint 主币 mint 地址
|
|
47
|
+
* @param admin Pool 管理员
|
|
48
|
+
* @param payer 支付账户
|
|
49
|
+
* @param config Pool 配置
|
|
50
|
+
* @returns Pool 公钥和交易签名
|
|
51
|
+
*/
|
|
52
|
+
async createPool(mainTokenMint, config = { feeNumerator: 3, feeDenominator: 1000 }) {
|
|
53
|
+
const pool = Keypair.generate();
|
|
54
|
+
const wallet = this.provider.publicKey;
|
|
55
|
+
const [poolAuthority] = this.derivePoolAuthority(pool.publicKey);
|
|
56
|
+
const [poolVault] = this.derivePoolVault(pool.publicKey);
|
|
57
|
+
const poolSize = 24704;
|
|
58
|
+
const lamports = await this.provider.connection.getMinimumBalanceForRentExemption(poolSize);
|
|
59
|
+
const createPoolAccountIx = SystemProgram.createAccount({
|
|
60
|
+
fromPubkey: wallet,
|
|
61
|
+
newAccountPubkey: pool.publicKey,
|
|
62
|
+
lamports,
|
|
63
|
+
space: poolSize,
|
|
64
|
+
programId: this.program.programId,
|
|
65
|
+
});
|
|
66
|
+
const signature = await this.program.methods
|
|
67
|
+
.createPool(new BN(config.feeNumerator), new BN(config.feeDenominator))
|
|
68
|
+
.accountsPartial({
|
|
69
|
+
pool: pool.publicKey,
|
|
70
|
+
poolAuthority,
|
|
71
|
+
mainTokenMint,
|
|
72
|
+
poolVault,
|
|
73
|
+
admin: wallet,
|
|
74
|
+
payer: wallet,
|
|
75
|
+
})
|
|
76
|
+
.preInstructions([createPoolAccountIx])
|
|
77
|
+
.signers([pool])
|
|
78
|
+
.rpc();
|
|
79
|
+
return { pool: pool.publicKey, signature };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 添加质押类型到 Pool
|
|
83
|
+
* @param pool Pool 公钥
|
|
84
|
+
* @returns LP mint 公钥和交易签名
|
|
85
|
+
*/
|
|
86
|
+
async addTokenToPool(pool) {
|
|
87
|
+
const lpMint = Keypair.generate();
|
|
88
|
+
const wallet = this.provider.publicKey;
|
|
89
|
+
const [poolAuthority] = this.derivePoolAuthority(pool);
|
|
90
|
+
const signature = await this.program.methods
|
|
91
|
+
.addTokenToPool()
|
|
92
|
+
.accountsPartial({
|
|
93
|
+
pool,
|
|
94
|
+
poolAuthority,
|
|
95
|
+
lpMint: lpMint.publicKey,
|
|
96
|
+
admin: wallet,
|
|
97
|
+
payer: wallet,
|
|
98
|
+
})
|
|
99
|
+
.signers([lpMint])
|
|
100
|
+
.rpc();
|
|
101
|
+
return { lpMint: lpMint.publicKey, signature };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 从 Pool 移除质押类型
|
|
105
|
+
* @param pool Pool 公钥
|
|
106
|
+
* @param lpMint LP mint 公钥
|
|
107
|
+
* @param admin 管理员
|
|
108
|
+
* @returns 交易签名
|
|
109
|
+
*/
|
|
110
|
+
async removeTokenFromPool(pool, lpMint, admin) {
|
|
111
|
+
const signature = await this.program.methods
|
|
112
|
+
.removeTokenFromPool()
|
|
113
|
+
.accounts({
|
|
114
|
+
pool,
|
|
115
|
+
lpMint,
|
|
116
|
+
admin: admin.publicKey,
|
|
117
|
+
})
|
|
118
|
+
.signers([admin])
|
|
119
|
+
.rpc();
|
|
120
|
+
return signature;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 修改 Token 权重
|
|
124
|
+
* @param pool Pool 公钥
|
|
125
|
+
* @param params 权重参数
|
|
126
|
+
* @param admin 管理员
|
|
127
|
+
* @returns 交易签名
|
|
128
|
+
*/
|
|
129
|
+
async modifyTokenWeight(pool, params, admin) {
|
|
130
|
+
const weights = params.weights.map((w) => typeof w === "number" ? new BN(w) : w);
|
|
131
|
+
const signature = await this.program.methods
|
|
132
|
+
.modifyTokenWeight(weights)
|
|
133
|
+
.accounts({
|
|
134
|
+
pool,
|
|
135
|
+
admin: admin.publicKey,
|
|
136
|
+
})
|
|
137
|
+
.remainingAccounts(params.tokenMints.map((mint) => ({
|
|
138
|
+
pubkey: mint,
|
|
139
|
+
isSigner: false,
|
|
140
|
+
isWritable: false,
|
|
141
|
+
})))
|
|
142
|
+
.signers([admin])
|
|
143
|
+
.rpc();
|
|
144
|
+
return signature;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 质押主币,铸造 LP 凭证
|
|
148
|
+
*/
|
|
149
|
+
async stake(pool, itemIndex, lpMint, amount) {
|
|
150
|
+
const wallet = this.provider.publicKey;
|
|
151
|
+
const [poolVault] = this.derivePoolVault(pool);
|
|
152
|
+
// Convert amount to BN with proper decimals (9 decimals for SOL/WSOL)
|
|
153
|
+
const amountBN = typeof amount === "number" ? new BN(amount * 1e9) : amount;
|
|
154
|
+
// Get pool info to get main token mint
|
|
155
|
+
const poolInfo = await this.getPoolInfo(pool);
|
|
156
|
+
const mainTokenMint = poolInfo.poolMint;
|
|
157
|
+
const userMainToken = await getAssociatedTokenAddress(mainTokenMint, wallet);
|
|
158
|
+
// Get or create user's LP token account
|
|
159
|
+
const userLpToken = await getAssociatedTokenAddress(lpMint, wallet);
|
|
160
|
+
// Check if accounts exist, if not, create them
|
|
161
|
+
const preInstructions = [];
|
|
162
|
+
// Check user main token account
|
|
163
|
+
const mainTokenAccountInfo = await this.provider.connection.getAccountInfo(userMainToken);
|
|
164
|
+
if (!mainTokenAccountInfo) {
|
|
165
|
+
const { createAssociatedTokenAccountInstruction } = await import("@solana/spl-token");
|
|
166
|
+
preInstructions.push(createAssociatedTokenAccountInstruction(wallet, userMainToken, wallet, mainTokenMint));
|
|
167
|
+
}
|
|
168
|
+
// Check user LP token account
|
|
169
|
+
const lpTokenAccountInfo = await this.provider.connection.getAccountInfo(userLpToken);
|
|
170
|
+
if (!lpTokenAccountInfo) {
|
|
171
|
+
const { createAssociatedTokenAccountInstruction } = await import("@solana/spl-token");
|
|
172
|
+
preInstructions.push(createAssociatedTokenAccountInstruction(wallet, userLpToken, wallet, lpMint));
|
|
173
|
+
}
|
|
174
|
+
const signature = await this.program.methods
|
|
175
|
+
.stake(itemIndex, amountBN)
|
|
176
|
+
.accountsPartial({
|
|
177
|
+
pool,
|
|
178
|
+
poolVault,
|
|
179
|
+
lpMint,
|
|
180
|
+
userMainToken,
|
|
181
|
+
userLpToken,
|
|
182
|
+
user: wallet,
|
|
183
|
+
})
|
|
184
|
+
.preInstructions(preInstructions)
|
|
185
|
+
.rpc();
|
|
186
|
+
return signature;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 销毁 LP 凭证,赎回主币
|
|
190
|
+
*/
|
|
191
|
+
async unstake(pool, itemIndex, lpMint, lpAmount) {
|
|
192
|
+
const wallet = this.provider.publicKey;
|
|
193
|
+
const [poolVault] = this.derivePoolVault(pool);
|
|
194
|
+
// Convert LP amount to BN with proper decimals (9 decimals for LP tokens)
|
|
195
|
+
const lpAmountBN = typeof lpAmount === "number" ? new BN(lpAmount * 1e9) : lpAmount;
|
|
196
|
+
// Get pool info to get main token mint
|
|
197
|
+
const poolInfo = await this.getPoolInfo(pool);
|
|
198
|
+
const mainTokenMint = poolInfo.poolMint;
|
|
199
|
+
const userMainToken = await getAssociatedTokenAddress(mainTokenMint, wallet);
|
|
200
|
+
const userLpToken = await getAssociatedTokenAddress(lpMint, wallet);
|
|
201
|
+
const signature = await this.program.methods
|
|
202
|
+
.unstake(itemIndex, lpAmountBN)
|
|
203
|
+
.accountsPartial({
|
|
204
|
+
pool,
|
|
205
|
+
poolVault,
|
|
206
|
+
lpMint,
|
|
207
|
+
userLpToken,
|
|
208
|
+
userMainToken,
|
|
209
|
+
user: wallet,
|
|
210
|
+
})
|
|
211
|
+
.rpc();
|
|
212
|
+
return signature;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* 获取 Pool 信息
|
|
216
|
+
*/
|
|
217
|
+
async getPoolInfo(pool) {
|
|
218
|
+
const poolAccount = await this.program.account.pool.fetch(pool);
|
|
219
|
+
let poolItems = [];
|
|
220
|
+
for (let i = 0; i < poolAccount.tokenCount; i++) {
|
|
221
|
+
const token = poolAccount.tokens[i];
|
|
222
|
+
if (token.mintAccount && token.mintAccount.toString() !== PublicKey.default.toString()) {
|
|
223
|
+
poolItems.push({
|
|
224
|
+
mintAccount: token.mintAccount,
|
|
225
|
+
mintAmount: token.mintAmount,
|
|
226
|
+
weight: token.weight
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
admin: poolAccount.admin,
|
|
232
|
+
poolVault: poolAccount.poolVault,
|
|
233
|
+
poolMint: poolAccount.poolMint,
|
|
234
|
+
tokenCount: poolAccount.tokenCount,
|
|
235
|
+
feeNumerator: poolAccount.feeNumerator,
|
|
236
|
+
feeDenominator: poolAccount.feeDenominator,
|
|
237
|
+
items: poolItems,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* 获取 Pool 中所有的 LP mint
|
|
242
|
+
*/
|
|
243
|
+
async getPoolLpMints(pool) {
|
|
244
|
+
const poolInfo = await this.getPoolInfo(pool);
|
|
245
|
+
return poolInfo.items.map((item) => item.mintAccount);
|
|
246
|
+
}
|
|
247
|
+
}
|