@cubee_ee/sdk 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/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/clients/AdminClient.d.ts +61 -0
- package/dist/clients/AdminClient.d.ts.map +1 -0
- package/dist/clients/AdminClient.js +196 -0
- package/dist/clients/AdminClient.js.map +1 -0
- package/dist/clients/CubeBackendClient.d.ts +67 -0
- package/dist/clients/CubeBackendClient.d.ts.map +1 -0
- package/dist/clients/CubeBackendClient.js +126 -0
- package/dist/clients/CubeBackendClient.js.map +1 -0
- package/dist/clients/CubicPoolClient.d.ts +73 -0
- package/dist/clients/CubicPoolClient.d.ts.map +1 -0
- package/dist/clients/CubicPoolClient.js +425 -0
- package/dist/clients/CubicPoolClient.js.map +1 -0
- package/dist/clients/PoolFactoryClient.d.ts +45 -0
- package/dist/clients/PoolFactoryClient.d.ts.map +1 -0
- package/dist/clients/PoolFactoryClient.js +83 -0
- package/dist/clients/PoolFactoryClient.js.map +1 -0
- package/dist/clients/RpcClient.d.ts +28 -0
- package/dist/clients/RpcClient.d.ts.map +1 -0
- package/dist/clients/RpcClient.js +58 -0
- package/dist/clients/RpcClient.js.map +1 -0
- package/dist/clients/SingleTokenDepositClient.d.ts +45 -0
- package/dist/clients/SingleTokenDepositClient.d.ts.map +1 -0
- package/dist/clients/SingleTokenDepositClient.js +63 -0
- package/dist/clients/SingleTokenDepositClient.js.map +1 -0
- package/dist/clients/index.d.ts +8 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +24 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/tx-builders.d.ts +32 -0
- package/dist/clients/tx-builders.d.ts.map +1 -0
- package/dist/clients/tx-builders.js +398 -0
- package/dist/clients/tx-builders.js.map +1 -0
- package/dist/config/index.d.ts +60 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +59 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/networks.d.ts +10 -0
- package/dist/config/networks.d.ts.map +1 -0
- package/dist/config/networks.js +31 -0
- package/dist/config/networks.js.map +1 -0
- package/dist/config/tokens.d.ts +19 -0
- package/dist/config/tokens.d.ts.map +1 -0
- package/dist/config/tokens.js +43 -0
- package/dist/config/tokens.js.map +1 -0
- package/dist/idl/cubic_pool.json +2497 -0
- package/dist/idl/index.d.ts +975 -0
- package/dist/idl/index.d.ts.map +1 -0
- package/dist/idl/index.js +18 -0
- package/dist/idl/index.js.map +1 -0
- package/dist/idl/protocol_admin.json +1816 -0
- package/dist/idl/single_token_liquidity.json +745 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/dist/math/cubicMath.d.ts +40 -0
- package/dist/math/cubicMath.d.ts.map +1 -0
- package/dist/math/cubicMath.js +75 -0
- package/dist/math/cubicMath.js.map +1 -0
- package/dist/math/fixedPoint.d.ts +14 -0
- package/dist/math/fixedPoint.d.ts.map +1 -0
- package/dist/math/fixedPoint.js +46 -0
- package/dist/math/fixedPoint.js.map +1 -0
- package/dist/math/index.d.ts +7 -0
- package/dist/math/index.d.ts.map +1 -0
- package/dist/math/index.js +23 -0
- package/dist/math/index.js.map +1 -0
- package/dist/math/logExp.d.ts +15 -0
- package/dist/math/logExp.d.ts.map +1 -0
- package/dist/math/logExp.js +91 -0
- package/dist/math/logExp.js.map +1 -0
- package/dist/math/singleToken.d.ts +53 -0
- package/dist/math/singleToken.d.ts.map +1 -0
- package/dist/math/singleToken.js +185 -0
- package/dist/math/singleToken.js.map +1 -0
- package/dist/math/slippage.d.ts +24 -0
- package/dist/math/slippage.d.ts.map +1 -0
- package/dist/math/slippage.js +54 -0
- package/dist/math/slippage.js.map +1 -0
- package/dist/math/weightedMath.d.ts +18 -0
- package/dist/math/weightedMath.d.ts.map +1 -0
- package/dist/math/weightedMath.js +45 -0
- package/dist/math/weightedMath.js.map +1 -0
- package/dist/parsers/borsh.d.ts +24 -0
- package/dist/parsers/borsh.d.ts.map +1 -0
- package/dist/parsers/borsh.js +80 -0
- package/dist/parsers/borsh.js.map +1 -0
- package/dist/parsers/events.d.ts +3 -0
- package/dist/parsers/events.d.ts.map +1 -0
- package/dist/parsers/events.js +172 -0
- package/dist/parsers/events.js.map +1 -0
- package/dist/parsers/index.d.ts +5 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +21 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/mintAccount.d.ts +22 -0
- package/dist/parsers/mintAccount.d.ts.map +1 -0
- package/dist/parsers/mintAccount.js +22 -0
- package/dist/parsers/mintAccount.js.map +1 -0
- package/dist/parsers/poolAccount.d.ts +32 -0
- package/dist/parsers/poolAccount.d.ts.map +1 -0
- package/dist/parsers/poolAccount.js +88 -0
- package/dist/parsers/poolAccount.js.map +1 -0
- package/dist/types/events.d.ts +82 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +3 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/pool.d.ts +66 -0
- package/dist/types/pool.d.ts.map +1 -0
- package/dist/types/pool.js +3 -0
- package/dist/types/pool.js.map +1 -0
- package/dist/types/result.d.ts +23 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +11 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/tx.d.ts +80 -0
- package/dist/types/tx.d.ts.map +1 -0
- package/dist/types/tx.js +3 -0
- package/dist/types/tx.js.map +1 -0
- package/dist/utils/errors.d.ts +8 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +83 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/pda.d.ts +8 -0
- package/dist/utils/pda.d.ts.map +1 -0
- package/dist/utils/pda.js +27 -0
- package/dist/utils/pda.js.map +1 -0
- package/dist/utils/retry.d.ts +22 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +62 -0
- package/dist/utils/retry.js.map +1 -0
- package/package.json +54 -0
- package/src/clients/AdminClient.ts +254 -0
- package/src/clients/CubeBackendClient.ts +193 -0
- package/src/clients/CubicPoolClient.ts +492 -0
- package/src/clients/PoolFactoryClient.ts +102 -0
- package/src/clients/RpcClient.ts +78 -0
- package/src/clients/SingleTokenDepositClient.ts +91 -0
- package/src/clients/index.ts +7 -0
- package/src/clients/tx-builders.ts +538 -0
- package/src/config/index.ts +82 -0
- package/src/config/networks.ts +49 -0
- package/src/config/tokens.ts +52 -0
- package/src/idl/cubic_pool.json +2497 -0
- package/src/idl/index.ts +13 -0
- package/src/idl/protocol_admin.json +1816 -0
- package/src/idl/single_token_liquidity.json +745 -0
- package/src/index.ts +154 -0
- package/src/math/cubicMath.ts +89 -0
- package/src/math/fixedPoint.ts +39 -0
- package/src/math/index.ts +6 -0
- package/src/math/logExp.ts +82 -0
- package/src/math/singleToken.ts +250 -0
- package/src/math/slippage.ts +49 -0
- package/src/math/weightedMath.ts +48 -0
- package/src/parsers/borsh.ts +80 -0
- package/src/parsers/events.ts +172 -0
- package/src/parsers/index.ts +4 -0
- package/src/parsers/mintAccount.ts +37 -0
- package/src/parsers/poolAccount.ts +113 -0
- package/src/types/events.ts +100 -0
- package/src/types/index.ts +4 -0
- package/src/types/pool.ts +64 -0
- package/src/types/result.ts +45 -0
- package/src/types/tx.ts +87 -0
- package/src/utils/errors.ts +78 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/pda.ts +58 -0
- package/src/utils/retry.ts +85 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountMeta,
|
|
3
|
+
ComputeBudgetProgram,
|
|
4
|
+
PublicKey,
|
|
5
|
+
SystemProgram,
|
|
6
|
+
TransactionInstruction,
|
|
7
|
+
} from "@solana/web3.js";
|
|
8
|
+
import {
|
|
9
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
10
|
+
TOKEN_PROGRAM_ID,
|
|
11
|
+
createAssociatedTokenAccountIdempotentInstruction,
|
|
12
|
+
} from "@solana/spl-token";
|
|
13
|
+
import BN from "bn.js";
|
|
14
|
+
import { CubeConfig } from "../config";
|
|
15
|
+
import { PoolInfo } from "../types/pool";
|
|
16
|
+
import {
|
|
17
|
+
AddLiquidityParams,
|
|
18
|
+
BuiltTx,
|
|
19
|
+
DeployPoolParams,
|
|
20
|
+
RemoveLiquidityParams,
|
|
21
|
+
SingleTokenDepositParams,
|
|
22
|
+
SwapParams,
|
|
23
|
+
} from "../types/tx";
|
|
24
|
+
import { deriveAta, deriveBptMint, deriveHelperPda } from "../utils/pda";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Low-level transaction builders. Emit raw `TransactionInstruction`s suitable
|
|
28
|
+
* for combination with others (e.g. versioned transactions with ALTs) in a
|
|
29
|
+
* single tx. Higher-level convenience lives on `CubicPoolClient`.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const CUBIC_POOL_DISC = {
|
|
33
|
+
swap: computeDiscriminator("swap"),
|
|
34
|
+
addLiquidity: computeDiscriminator("add_liquidity"),
|
|
35
|
+
removeLiquidity: computeDiscriminator("remove_liquidity"),
|
|
36
|
+
initializeCubicPool: computeDiscriminator("initialize_cubic_pool"),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const STLD_DISC = {
|
|
40
|
+
depositSingleToken: computeDiscriminator("deposit_single_token"),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Anchor discriminator: sha256("global:<ix_name>")[0..8]. The SDK
|
|
45
|
+
* pre-computes only the cases it needs.
|
|
46
|
+
*
|
|
47
|
+
* Pre-computed values (confirmed against `src/idl/*.json`):
|
|
48
|
+
* swap → f8c69e91e17587c8
|
|
49
|
+
* add_liquidity → b59d59438fb63448
|
|
50
|
+
* remove_liquidity → 5055d14818ceb16c
|
|
51
|
+
* initialize_cubic_pool → d79474cf79686f83
|
|
52
|
+
* deposit_single_token → a688a62fc7c056a9
|
|
53
|
+
*
|
|
54
|
+
* If you change an instruction name in Rust, regenerate by reading the
|
|
55
|
+
* target/idl/*.json discriminator field.
|
|
56
|
+
*/
|
|
57
|
+
function computeDiscriminator(ixName: string): Buffer {
|
|
58
|
+
// Fallback: Anchor exposes discriminators in the IDL. We ship the known
|
|
59
|
+
// ones as a static map; callers passing unknown names error clearly.
|
|
60
|
+
const KNOWN: Record<string, string> = {
|
|
61
|
+
swap: "f8c69e91e17587c8",
|
|
62
|
+
add_liquidity: "b59d59438fb63448",
|
|
63
|
+
remove_liquidity: "5055d14818ceb16c",
|
|
64
|
+
initialize_cubic_pool: "d79474cf79686f83",
|
|
65
|
+
deposit_single_token: "a688a62fc7c056a9",
|
|
66
|
+
initialize_config: "d07f1501c2bec446",
|
|
67
|
+
};
|
|
68
|
+
const hex = KNOWN[ixName];
|
|
69
|
+
if (!hex) throw new Error(`tx-builders: unknown discriminator for "${ixName}"`);
|
|
70
|
+
return Buffer.from(hex, "hex");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function requirePositiveMinimumBpt(minimumBptAmount: BN | undefined, ixName: string): BN {
|
|
74
|
+
if (!minimumBptAmount || minimumBptAmount.lte(new BN(0))) {
|
|
75
|
+
throw new Error(`${ixName}: minimumBptAmount must be positive`);
|
|
76
|
+
}
|
|
77
|
+
return minimumBptAmount;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ============================================================
|
|
81
|
+
// Swap
|
|
82
|
+
// ============================================================
|
|
83
|
+
|
|
84
|
+
export function buildSwapIx(
|
|
85
|
+
cfg: CubeConfig,
|
|
86
|
+
pool: PoolInfo,
|
|
87
|
+
params: SwapParams & { minAmountOut: BN }
|
|
88
|
+
): TransactionInstruction {
|
|
89
|
+
const inTok = pool.tokens[params.tokenInIndex];
|
|
90
|
+
const outTok = pool.tokens[params.tokenOutIndex];
|
|
91
|
+
|
|
92
|
+
const userTokenIn = deriveAta(params.user, inTok.mint, inTok.tokenProgram);
|
|
93
|
+
const userTokenOut = deriveAta(params.user, outTok.mint, outTok.tokenProgram);
|
|
94
|
+
|
|
95
|
+
const data = Buffer.concat([
|
|
96
|
+
CUBIC_POOL_DISC.swap,
|
|
97
|
+
encodeU64(params.amountIn),
|
|
98
|
+
encodeU64(params.minAmountOut),
|
|
99
|
+
encodeU8(params.tokenInIndex),
|
|
100
|
+
encodeU8(params.tokenOutIndex),
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
const keys: AccountMeta[] = [
|
|
104
|
+
{ pubkey: pool.address, isSigner: false, isWritable: true },
|
|
105
|
+
{ pubkey: inTok.mint, isSigner: false, isWritable: false },
|
|
106
|
+
{ pubkey: outTok.mint, isSigner: false, isWritable: false },
|
|
107
|
+
{ pubkey: userTokenIn, isSigner: false, isWritable: true },
|
|
108
|
+
{ pubkey: userTokenOut, isSigner: false, isWritable: true },
|
|
109
|
+
{ pubkey: inTok.vault, isSigner: false, isWritable: true },
|
|
110
|
+
{ pubkey: outTok.vault, isSigner: false, isWritable: true },
|
|
111
|
+
{ pubkey: params.user, isSigner: true, isWritable: true },
|
|
112
|
+
{ pubkey: inTok.tokenProgram, isSigner: false, isWritable: false },
|
|
113
|
+
{ pubkey: outTok.tokenProgram, isSigner: false, isWritable: false },
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
return new TransactionInstruction({
|
|
117
|
+
programId: cfg.programs.cubicPool,
|
|
118
|
+
keys,
|
|
119
|
+
data,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function buildSwapTx(
|
|
124
|
+
cfg: CubeConfig,
|
|
125
|
+
pool: PoolInfo,
|
|
126
|
+
params: SwapParams & { minAmountOut: BN }
|
|
127
|
+
): BuiltTx {
|
|
128
|
+
return {
|
|
129
|
+
instructions: [
|
|
130
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 }),
|
|
131
|
+
buildSwapIx(cfg, pool, params),
|
|
132
|
+
],
|
|
133
|
+
suggestedCuLimit: 400_000,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ============================================================
|
|
138
|
+
// Add liquidity (proportional)
|
|
139
|
+
// ============================================================
|
|
140
|
+
|
|
141
|
+
export function buildAddLiquidityIx(
|
|
142
|
+
cfg: CubeConfig,
|
|
143
|
+
pool: PoolInfo,
|
|
144
|
+
params: AddLiquidityParams
|
|
145
|
+
): TransactionInstruction {
|
|
146
|
+
const userBpt = deriveAta(params.user, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
147
|
+
const minBpt = requirePositiveMinimumBpt(params.minimumBptAmount, "add_liquidity");
|
|
148
|
+
|
|
149
|
+
const data = Buffer.concat([
|
|
150
|
+
CUBIC_POOL_DISC.addLiquidity,
|
|
151
|
+
encodeVecU64(params.tokenAmounts),
|
|
152
|
+
encodeU64(minBpt),
|
|
153
|
+
]);
|
|
154
|
+
|
|
155
|
+
// remaining_accounts layout:
|
|
156
|
+
// [user_token_i, vault_i] × N, mint_i × N, token_program_i × N
|
|
157
|
+
const remaining: AccountMeta[] = [];
|
|
158
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
159
|
+
const t = pool.tokens[i];
|
|
160
|
+
const userAta = deriveAta(params.user, t.mint, t.tokenProgram);
|
|
161
|
+
remaining.push({ pubkey: userAta, isSigner: false, isWritable: true });
|
|
162
|
+
remaining.push({ pubkey: t.vault, isSigner: false, isWritable: true });
|
|
163
|
+
}
|
|
164
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
165
|
+
remaining.push({ pubkey: pool.tokens[i].mint, isSigner: false, isWritable: false });
|
|
166
|
+
}
|
|
167
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
168
|
+
remaining.push({ pubkey: pool.tokens[i].tokenProgram, isSigner: false, isWritable: false });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const keys: AccountMeta[] = [
|
|
172
|
+
{ pubkey: pool.address, isSigner: false, isWritable: true },
|
|
173
|
+
{ pubkey: pool.bptMint, isSigner: false, isWritable: true },
|
|
174
|
+
{ pubkey: userBpt, isSigner: false, isWritable: true },
|
|
175
|
+
{ pubkey: params.user, isSigner: true, isWritable: true },
|
|
176
|
+
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
177
|
+
...remaining,
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
return new TransactionInstruction({
|
|
181
|
+
programId: cfg.programs.cubicPool,
|
|
182
|
+
keys,
|
|
183
|
+
data,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function buildAddLiquidityTx(
|
|
188
|
+
cfg: CubeConfig,
|
|
189
|
+
pool: PoolInfo,
|
|
190
|
+
params: AddLiquidityParams
|
|
191
|
+
): BuiltTx {
|
|
192
|
+
const userBpt = deriveAta(params.user, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
193
|
+
return {
|
|
194
|
+
instructions: [
|
|
195
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 600_000 }),
|
|
196
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
197
|
+
params.user,
|
|
198
|
+
userBpt,
|
|
199
|
+
params.user,
|
|
200
|
+
pool.bptMint,
|
|
201
|
+
TOKEN_PROGRAM_ID
|
|
202
|
+
),
|
|
203
|
+
buildAddLiquidityIx(cfg, pool, params),
|
|
204
|
+
],
|
|
205
|
+
suggestedCuLimit: 600_000,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ============================================================
|
|
210
|
+
// Remove liquidity
|
|
211
|
+
// ============================================================
|
|
212
|
+
|
|
213
|
+
export function buildRemoveLiquidityIx(
|
|
214
|
+
cfg: CubeConfig,
|
|
215
|
+
pool: PoolInfo,
|
|
216
|
+
params: RemoveLiquidityParams
|
|
217
|
+
): TransactionInstruction {
|
|
218
|
+
const userBpt = deriveAta(params.user, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
219
|
+
const mins = params.minimumTokenAmounts ?? pool.tokens.map(() => new BN(0));
|
|
220
|
+
|
|
221
|
+
const data = Buffer.concat([
|
|
222
|
+
CUBIC_POOL_DISC.removeLiquidity,
|
|
223
|
+
encodeU64(params.bptAmount),
|
|
224
|
+
encodeVecU64(mins),
|
|
225
|
+
]);
|
|
226
|
+
|
|
227
|
+
// remove_liquidity remaining_accounts format:
|
|
228
|
+
// [vault_i, user_token_i] × N, mint_i × N, token_program_i × N
|
|
229
|
+
const remaining: AccountMeta[] = [];
|
|
230
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
231
|
+
const t = pool.tokens[i];
|
|
232
|
+
const userAta = deriveAta(params.user, t.mint, t.tokenProgram);
|
|
233
|
+
remaining.push({ pubkey: t.vault, isSigner: false, isWritable: true });
|
|
234
|
+
remaining.push({ pubkey: userAta, isSigner: false, isWritable: true });
|
|
235
|
+
}
|
|
236
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
237
|
+
remaining.push({ pubkey: pool.tokens[i].mint, isSigner: false, isWritable: false });
|
|
238
|
+
}
|
|
239
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
240
|
+
remaining.push({ pubkey: pool.tokens[i].tokenProgram, isSigner: false, isWritable: false });
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const keys: AccountMeta[] = [
|
|
244
|
+
{ pubkey: pool.address, isSigner: false, isWritable: true },
|
|
245
|
+
{ pubkey: pool.bptMint, isSigner: false, isWritable: true },
|
|
246
|
+
{ pubkey: userBpt, isSigner: false, isWritable: true },
|
|
247
|
+
{ pubkey: params.user, isSigner: true, isWritable: true },
|
|
248
|
+
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
249
|
+
...remaining,
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
return new TransactionInstruction({
|
|
253
|
+
programId: cfg.programs.cubicPool,
|
|
254
|
+
keys,
|
|
255
|
+
data,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function buildRemoveLiquidityTx(
|
|
260
|
+
cfg: CubeConfig,
|
|
261
|
+
pool: PoolInfo,
|
|
262
|
+
params: RemoveLiquidityParams
|
|
263
|
+
): BuiltTx {
|
|
264
|
+
const ixs: TransactionInstruction[] = [
|
|
265
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: cfg.defaults.cuLimit }),
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
// The contract transfers every pool token to the user's ATA. Include
|
|
269
|
+
// idempotent creates so a proportional burn works even when the user never
|
|
270
|
+
// held one of the receive tokens before.
|
|
271
|
+
for (const t of pool.tokens) {
|
|
272
|
+
const userAta = deriveAta(params.user, t.mint, t.tokenProgram);
|
|
273
|
+
ixs.push(
|
|
274
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
275
|
+
params.user,
|
|
276
|
+
userAta,
|
|
277
|
+
params.user,
|
|
278
|
+
t.mint,
|
|
279
|
+
t.tokenProgram
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
ixs.push(buildRemoveLiquidityIx(cfg, pool, params));
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
instructions: ixs,
|
|
288
|
+
suggestedCuLimit: cfg.defaults.cuLimit,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ============================================================
|
|
293
|
+
// Single-token deposit (helper program)
|
|
294
|
+
// ============================================================
|
|
295
|
+
|
|
296
|
+
export function buildSingleTokenDepositIx(
|
|
297
|
+
cfg: CubeConfig,
|
|
298
|
+
pool: PoolInfo,
|
|
299
|
+
params: SingleTokenDepositParams
|
|
300
|
+
): TransactionInstruction {
|
|
301
|
+
const slip = params.slippageHundredthsBps ?? cfg.defaults.slippageHundredthsBps;
|
|
302
|
+
const minBpt = requirePositiveMinimumBpt(params.minimumBptAmount, "deposit_single_token");
|
|
303
|
+
const [helper] = deriveHelperPda(cfg.programs.singleTokenLiquidity, pool.address);
|
|
304
|
+
const helperBpt = deriveAta(helper, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
305
|
+
const userBpt = deriveAta(params.user, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
306
|
+
|
|
307
|
+
const data = Buffer.concat([
|
|
308
|
+
STLD_DISC.depositSingleToken,
|
|
309
|
+
encodeU64(params.amountIn),
|
|
310
|
+
encodeU8(params.tokenInIndex),
|
|
311
|
+
encodeU32(slip),
|
|
312
|
+
encodeU64(minBpt),
|
|
313
|
+
]);
|
|
314
|
+
|
|
315
|
+
// stld remaining_accounts: [mint_i, user_ata_i, helper_ata_i, vault_i, tp_i] × N
|
|
316
|
+
const remaining: AccountMeta[] = [];
|
|
317
|
+
for (let i = 0; i < pool.tokenCount; i++) {
|
|
318
|
+
const t = pool.tokens[i];
|
|
319
|
+
const userAta = deriveAta(params.user, t.mint, t.tokenProgram);
|
|
320
|
+
const helperAta = deriveAta(helper, t.mint, t.tokenProgram);
|
|
321
|
+
remaining.push({ pubkey: t.mint, isSigner: false, isWritable: false });
|
|
322
|
+
remaining.push({ pubkey: userAta, isSigner: false, isWritable: true });
|
|
323
|
+
remaining.push({ pubkey: helperAta, isSigner: false, isWritable: true });
|
|
324
|
+
remaining.push({ pubkey: t.vault, isSigner: false, isWritable: true });
|
|
325
|
+
remaining.push({ pubkey: t.tokenProgram, isSigner: false, isWritable: false });
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const keys: AccountMeta[] = [
|
|
329
|
+
{ pubkey: pool.address, isSigner: false, isWritable: true },
|
|
330
|
+
{ pubkey: helper, isSigner: false, isWritable: false },
|
|
331
|
+
{ pubkey: pool.bptMint, isSigner: false, isWritable: true },
|
|
332
|
+
{ pubkey: helperBpt, isSigner: false, isWritable: true },
|
|
333
|
+
{ pubkey: userBpt, isSigner: false, isWritable: true },
|
|
334
|
+
{ pubkey: params.user, isSigner: true, isWritable: true },
|
|
335
|
+
{ pubkey: cfg.programs.cubicPool, isSigner: false, isWritable: false },
|
|
336
|
+
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
337
|
+
...remaining,
|
|
338
|
+
];
|
|
339
|
+
|
|
340
|
+
return new TransactionInstruction({
|
|
341
|
+
programId: cfg.programs.singleTokenLiquidity,
|
|
342
|
+
keys,
|
|
343
|
+
data,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Full single-token deposit tx: makes sure helper ATAs and the user's
|
|
349
|
+
* per-token ATAs exist (idempotent create instructions), creates the user's
|
|
350
|
+
* BPT ATA if absent, then the deposit ix itself. The helper program validates
|
|
351
|
+
* all user ATAs up front because it may refund dust for any pool token.
|
|
352
|
+
* CU limit set to 1.4M (mainnet/devnet max).
|
|
353
|
+
*/
|
|
354
|
+
export function buildSingleTokenDepositTx(
|
|
355
|
+
cfg: CubeConfig,
|
|
356
|
+
pool: PoolInfo,
|
|
357
|
+
params: SingleTokenDepositParams
|
|
358
|
+
): BuiltTx {
|
|
359
|
+
const [helper] = deriveHelperPda(cfg.programs.singleTokenLiquidity, pool.address);
|
|
360
|
+
const helperBpt = deriveAta(helper, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
361
|
+
const userBpt = deriveAta(params.user, pool.bptMint, TOKEN_PROGRAM_ID);
|
|
362
|
+
|
|
363
|
+
const ixs: TransactionInstruction[] = [
|
|
364
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: cfg.defaults.cuLimit }),
|
|
365
|
+
];
|
|
366
|
+
// User + helper ATAs (helper has an off-curve owner). Idempotent — safe to
|
|
367
|
+
// include even when the accounts already exist.
|
|
368
|
+
for (const t of pool.tokens) {
|
|
369
|
+
const userAta = deriveAta(params.user, t.mint, t.tokenProgram);
|
|
370
|
+
const helperAta = deriveAta(helper, t.mint, t.tokenProgram);
|
|
371
|
+
ixs.push(
|
|
372
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
373
|
+
params.user,
|
|
374
|
+
userAta,
|
|
375
|
+
params.user,
|
|
376
|
+
t.mint,
|
|
377
|
+
t.tokenProgram
|
|
378
|
+
)
|
|
379
|
+
);
|
|
380
|
+
ixs.push(
|
|
381
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
382
|
+
params.user,
|
|
383
|
+
helperAta,
|
|
384
|
+
helper,
|
|
385
|
+
t.mint,
|
|
386
|
+
t.tokenProgram
|
|
387
|
+
)
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
ixs.push(
|
|
391
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
392
|
+
params.user,
|
|
393
|
+
helperBpt,
|
|
394
|
+
helper,
|
|
395
|
+
pool.bptMint,
|
|
396
|
+
TOKEN_PROGRAM_ID
|
|
397
|
+
)
|
|
398
|
+
);
|
|
399
|
+
ixs.push(
|
|
400
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
401
|
+
params.user,
|
|
402
|
+
userBpt,
|
|
403
|
+
params.user,
|
|
404
|
+
pool.bptMint,
|
|
405
|
+
TOKEN_PROGRAM_ID
|
|
406
|
+
)
|
|
407
|
+
);
|
|
408
|
+
ixs.push(buildSingleTokenDepositIx(cfg, pool, params));
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
instructions: ixs,
|
|
412
|
+
suggestedCuLimit: cfg.defaults.cuLimit,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ============================================================
|
|
417
|
+
// Deploy new pool (PoolFactory)
|
|
418
|
+
// ============================================================
|
|
419
|
+
|
|
420
|
+
export function buildInitializeConfigIx(
|
|
421
|
+
cfg: CubeConfig,
|
|
422
|
+
params: { config: PublicKey; payer: PublicKey; defaultProtocolFeeRate: number }
|
|
423
|
+
): TransactionInstruction {
|
|
424
|
+
// cubic_pool v0.6.0 initialize_config:
|
|
425
|
+
// - the program now enforces `protocol_admin == TreasuryPDA(protocol-admin)`
|
|
426
|
+
// - the Treasury PDA is passed as an account; Anchor derives it from
|
|
427
|
+
// seeds [b"treasury"] on the protocol-admin program ID and rejects
|
|
428
|
+
// anything else, so neither the caller nor the SDK can substitute
|
|
429
|
+
// a wallet here. The on-chain `config.protocol_admin` field will
|
|
430
|
+
// always be this PDA.
|
|
431
|
+
const [treasuryPda] = PublicKey.findProgramAddressSync(
|
|
432
|
+
[Buffer.from("treasury")],
|
|
433
|
+
cfg.programs.protocolAdmin
|
|
434
|
+
);
|
|
435
|
+
const data = Buffer.concat([
|
|
436
|
+
computeDiscriminator("initialize_config"),
|
|
437
|
+
treasuryPda.toBuffer(),
|
|
438
|
+
encodeU16(params.defaultProtocolFeeRate),
|
|
439
|
+
]);
|
|
440
|
+
const keys: AccountMeta[] = [
|
|
441
|
+
{ pubkey: params.config, isSigner: true, isWritable: true },
|
|
442
|
+
{ pubkey: treasuryPda, isSigner: false, isWritable: false },
|
|
443
|
+
{ pubkey: params.payer, isSigner: true, isWritable: true },
|
|
444
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
445
|
+
];
|
|
446
|
+
return new TransactionInstruction({
|
|
447
|
+
programId: cfg.programs.cubicPool,
|
|
448
|
+
keys,
|
|
449
|
+
data,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export function buildInitializeCubicPoolIx(
|
|
454
|
+
cfg: CubeConfig,
|
|
455
|
+
params: DeployPoolParams
|
|
456
|
+
): TransactionInstruction {
|
|
457
|
+
const tokenProgram = params.bptTokenProgram ?? TOKEN_PROGRAM_ID;
|
|
458
|
+
const [pool] = PublicKey.findProgramAddressSync(
|
|
459
|
+
[Buffer.from("cubic_pool"), params.configKey.toBuffer(), params.poolId.toArrayLike(Buffer, "le", 8)],
|
|
460
|
+
cfg.programs.cubicPool
|
|
461
|
+
);
|
|
462
|
+
const [bptMint] = deriveBptMint(cfg.programs.cubicPool, pool);
|
|
463
|
+
|
|
464
|
+
const data = Buffer.concat([
|
|
465
|
+
CUBIC_POOL_DISC.initializeCubicPool,
|
|
466
|
+
encodeVecPubkey(params.tokens),
|
|
467
|
+
encodeVecU64(params.weightsBps.map((w) => new BN(w))),
|
|
468
|
+
encodeVecU64(params.virtualBalances),
|
|
469
|
+
encodeU32(params.swapFeeRate),
|
|
470
|
+
encodeU64(params.poolId),
|
|
471
|
+
]);
|
|
472
|
+
|
|
473
|
+
const remaining: AccountMeta[] = params.tokens.map((m) => ({
|
|
474
|
+
pubkey: m,
|
|
475
|
+
isSigner: false,
|
|
476
|
+
isWritable: false,
|
|
477
|
+
}));
|
|
478
|
+
|
|
479
|
+
const keys: AccountMeta[] = [
|
|
480
|
+
{ pubkey: params.configKey, isSigner: false, isWritable: false },
|
|
481
|
+
{ pubkey: pool, isSigner: false, isWritable: true },
|
|
482
|
+
{ pubkey: bptMint, isSigner: false, isWritable: true },
|
|
483
|
+
{ pubkey: params.payer, isSigner: true, isWritable: true },
|
|
484
|
+
{ pubkey: tokenProgram, isSigner: false, isWritable: false },
|
|
485
|
+
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
486
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
487
|
+
...remaining,
|
|
488
|
+
];
|
|
489
|
+
|
|
490
|
+
return new TransactionInstruction({
|
|
491
|
+
programId: cfg.programs.cubicPool,
|
|
492
|
+
keys,
|
|
493
|
+
data,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export function buildDeployPoolTx(cfg: CubeConfig, params: DeployPoolParams): BuiltTx {
|
|
498
|
+
return {
|
|
499
|
+
instructions: [
|
|
500
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 }),
|
|
501
|
+
buildInitializeCubicPoolIx(cfg, params),
|
|
502
|
+
],
|
|
503
|
+
suggestedCuLimit: 400_000,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ============================================================
|
|
508
|
+
// Borsh encoding helpers (subset used above)
|
|
509
|
+
// ============================================================
|
|
510
|
+
|
|
511
|
+
function encodeU8(v: number): Buffer {
|
|
512
|
+
const b = Buffer.alloc(1);
|
|
513
|
+
b.writeUInt8(v & 0xff, 0);
|
|
514
|
+
return b;
|
|
515
|
+
}
|
|
516
|
+
function encodeU16(v: number): Buffer {
|
|
517
|
+
const b = Buffer.alloc(2);
|
|
518
|
+
b.writeUInt16LE(v & 0xffff, 0);
|
|
519
|
+
return b;
|
|
520
|
+
}
|
|
521
|
+
function encodeU32(v: number): Buffer {
|
|
522
|
+
const b = Buffer.alloc(4);
|
|
523
|
+
b.writeUInt32LE(v >>> 0, 0);
|
|
524
|
+
return b;
|
|
525
|
+
}
|
|
526
|
+
function encodeU64(v: BN): Buffer {
|
|
527
|
+
return v.toArrayLike(Buffer, "le", 8);
|
|
528
|
+
}
|
|
529
|
+
function encodeVecU64(vs: BN[]): Buffer {
|
|
530
|
+
const len = Buffer.alloc(4);
|
|
531
|
+
len.writeUInt32LE(vs.length, 0);
|
|
532
|
+
return Buffer.concat([len, ...vs.map(encodeU64)]);
|
|
533
|
+
}
|
|
534
|
+
function encodeVecPubkey(pks: PublicKey[]): Buffer {
|
|
535
|
+
const len = Buffer.alloc(4);
|
|
536
|
+
len.writeUInt32LE(pks.length, 0);
|
|
537
|
+
return Buffer.concat([len, ...pks.map((p) => p.toBuffer())]);
|
|
538
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Commitment, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import { NETWORK_PROGRAMS, NetworkPrograms, Network, DEFAULT_RPC_ENDPOINT } from "./networks";
|
|
3
|
+
import { TokenInfo } from "./tokens";
|
|
4
|
+
|
|
5
|
+
export * from "./networks";
|
|
6
|
+
export * from "./tokens";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Root SDK configuration. Passed into every Client class at construction.
|
|
10
|
+
* Immutable after creation — rebuild if you need to switch networks.
|
|
11
|
+
*/
|
|
12
|
+
export interface CubeConfig {
|
|
13
|
+
network: Network;
|
|
14
|
+
programs: NetworkPrograms;
|
|
15
|
+
defaults: {
|
|
16
|
+
rpcEndpoint: string;
|
|
17
|
+
rpcCommitment: Commitment;
|
|
18
|
+
/** Used by helpers that prepend a ComputeBudget instruction. */
|
|
19
|
+
cuLimit: number;
|
|
20
|
+
/**
|
|
21
|
+
* Default slippage budget when the caller doesn't pass one. Units:
|
|
22
|
+
* hundredths of a basis point (matches cubic-pool's `swap_fee_rate`
|
|
23
|
+
* scale). 50_000 = 5%.
|
|
24
|
+
*/
|
|
25
|
+
slippageHundredthsBps: number;
|
|
26
|
+
};
|
|
27
|
+
/** Optional token registry keyed by mint pubkey string. */
|
|
28
|
+
tokens?: Record<string, TokenInfo>;
|
|
29
|
+
/** Optional backend endpoint; consumed by CubeBackendClient. */
|
|
30
|
+
backendEndpoint?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface CubeConfigOverrides {
|
|
34
|
+
rpcEndpoint?: string;
|
|
35
|
+
rpcCommitment?: Commitment;
|
|
36
|
+
cuLimit?: number;
|
|
37
|
+
slippageHundredthsBps?: number;
|
|
38
|
+
backendEndpoint?: string;
|
|
39
|
+
tokens?: Record<string, TokenInfo>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Build a CubeConfig for the named network with optional overrides. */
|
|
43
|
+
export function getConfig(network: Network, overrides: CubeConfigOverrides = {}): CubeConfig {
|
|
44
|
+
return {
|
|
45
|
+
network,
|
|
46
|
+
programs: NETWORK_PROGRAMS[network],
|
|
47
|
+
defaults: {
|
|
48
|
+
rpcEndpoint: overrides.rpcEndpoint ?? DEFAULT_RPC_ENDPOINT[network],
|
|
49
|
+
rpcCommitment: overrides.rpcCommitment ?? "confirmed",
|
|
50
|
+
cuLimit: overrides.cuLimit ?? 1_400_000,
|
|
51
|
+
slippageHundredthsBps: overrides.slippageHundredthsBps ?? 50_000,
|
|
52
|
+
},
|
|
53
|
+
tokens: overrides.tokens,
|
|
54
|
+
backendEndpoint: overrides.backendEndpoint,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const CUBIC_POOL_SEED = Buffer.from("cubic_pool");
|
|
59
|
+
export const BPT_MINT_SEED = Buffer.from("bpt_mint");
|
|
60
|
+
export const STLD_HELPER_SEED = Buffer.from("stld_helper");
|
|
61
|
+
export const TREASURY_SEED = Buffer.from("treasury");
|
|
62
|
+
|
|
63
|
+
/** Contract-level constants mirrored from Rust. */
|
|
64
|
+
export const WEIGHT_SCALE = 10_000; // 100 %
|
|
65
|
+
export const MIN_WEIGHT = 100; // 1 %
|
|
66
|
+
export const MAX_WEIGHT = 9_900; // 99 %
|
|
67
|
+
export const MIN_TOKENS = 2;
|
|
68
|
+
export const MAX_TOKENS = 10;
|
|
69
|
+
export const BPT_DECIMALS = 9;
|
|
70
|
+
export const SWAP_FEE_PRECISION = 1_000_000; // 100 %
|
|
71
|
+
export const PROTOCOL_FEE_PRECISION = 10_000; // 100 %
|
|
72
|
+
export const MAX_SWAP_FEE_RATE = 100_000; // 10 %
|
|
73
|
+
export const MAX_PROTOCOL_FEE_RATE = 5_000; // 50 %
|
|
74
|
+
export const MINIMUM_INITIAL_BPT = 1_000n;
|
|
75
|
+
export const SLIPPAGE_PRECISION = 1_000_000;
|
|
76
|
+
export const MIN_SLIPPAGE_HBPS = 10; // 0.001 %
|
|
77
|
+
|
|
78
|
+
export type ProgramIdKind = "cubicPool" | "singleTokenLiquidity" | "protocolAdmin";
|
|
79
|
+
|
|
80
|
+
export function programId(cfg: CubeConfig, kind: ProgramIdKind): PublicKey {
|
|
81
|
+
return cfg.programs[kind];
|
|
82
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
|
|
3
|
+
export type Network = "mainnet" | "devnet" | "localnet";
|
|
4
|
+
|
|
5
|
+
export interface NetworkPrograms {
|
|
6
|
+
cubicPool: PublicKey;
|
|
7
|
+
singleTokenLiquidity: PublicKey;
|
|
8
|
+
protocolAdmin: PublicKey;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const NETWORK_PROGRAMS: Record<Network, NetworkPrograms> = {
|
|
12
|
+
mainnet: {
|
|
13
|
+
cubicPool: new PublicKey("8iQtGj9mcUfFUGaiCpPy89swC3s8YTC8FhVZWfgeZhwu"),
|
|
14
|
+
// TODO(mainnet): single_token_liquidity is NOT deployed on mainnet — this
|
|
15
|
+
// is the devnet program ID as a placeholder. Single-token deposit is
|
|
16
|
+
// disabled in the frontend. If/when stld ships on mainnet, replace this
|
|
17
|
+
// with the real mainnet program ID.
|
|
18
|
+
singleTokenLiquidity: new PublicKey(
|
|
19
|
+
"7BpdUH1tzTSXLuQNo6YpjJ8Eagw8AkrS6cnkxiJdCFS2"
|
|
20
|
+
),
|
|
21
|
+
protocolAdmin: new PublicKey(
|
|
22
|
+
"3jiojHZbjJQ7QLMGSTjFwxVEmx4NtuRy34nLAmsJME81"
|
|
23
|
+
),
|
|
24
|
+
},
|
|
25
|
+
devnet: {
|
|
26
|
+
cubicPool: new PublicKey("8iQtGj9mcUfFUGaiCpPy89swC3s8YTC8FhVZWfgeZhwu"),
|
|
27
|
+
singleTokenLiquidity: new PublicKey(
|
|
28
|
+
"7BpdUH1tzTSXLuQNo6YpjJ8Eagw8AkrS6cnkxiJdCFS2"
|
|
29
|
+
),
|
|
30
|
+
protocolAdmin: new PublicKey(
|
|
31
|
+
"3jiojHZbjJQ7QLMGSTjFwxVEmx4NtuRy34nLAmsJME81"
|
|
32
|
+
),
|
|
33
|
+
},
|
|
34
|
+
localnet: {
|
|
35
|
+
cubicPool: new PublicKey("8iQtGj9mcUfFUGaiCpPy89swC3s8YTC8FhVZWfgeZhwu"),
|
|
36
|
+
singleTokenLiquidity: new PublicKey(
|
|
37
|
+
"7BpdUH1tzTSXLuQNo6YpjJ8Eagw8AkrS6cnkxiJdCFS2"
|
|
38
|
+
),
|
|
39
|
+
protocolAdmin: new PublicKey(
|
|
40
|
+
"3jiojHZbjJQ7QLMGSTjFwxVEmx4NtuRy34nLAmsJME81"
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const DEFAULT_RPC_ENDPOINT: Record<Network, string> = {
|
|
46
|
+
mainnet: "https://api.mainnet-beta.solana.com",
|
|
47
|
+
devnet: "https://api.devnet.solana.com",
|
|
48
|
+
localnet: "http://127.0.0.1:8899",
|
|
49
|
+
};
|